示例#1
0
void usb_composite_force_reset(struct usb_composite_dev *cdev)
{
	unsigned long			flags;

	spin_lock_irqsave(&cdev->lock, flags);
	/* force reenumeration */
	if (cdev && cdev->gadget &&
			cdev->gadget->speed != USB_SPEED_UNKNOWN) {
		/*
		* Another USB disconnect event is reported from
		* controller before "disconnected" switch event is sent out.
		* This does happen. When force_reset is executed,
		* two reset interrupt occur - one for get descriptor,
		* one for bus enumeration.
		* To avoid unnecessary switch event ignited,
		* we set the flag "mute_switch" to 2.
		* This is a "hard" assumption that two
		* "disconnect" event will be reported
		*/
		cdev->mute_switch = 2;

		/* avoid sending a disconnect switch event until after we disconnect */
		spin_unlock_irqrestore(&cdev->lock, flags);

		usb_gadget_disconnect(cdev->gadget);
		msleep(10);
		usb_gadget_connect(cdev->gadget);
		usb_gadget_vbus_connect(cdev->gadget);
	} else {
		spin_unlock_irqrestore(&cdev->lock, flags);
	}
}
示例#2
0
static void isp1704_charger_work(struct work_struct *data)
{
	int			detect;
	struct isp1704_charger	*isp =
		container_of(data, struct isp1704_charger, work);

	/*
	 * FIXME Only supporting dedicated chargers even though isp1704 can
	 * detect HUB and HOST chargers. If the device has already been
	 * enumerated, the detection will break the connection.
	 */
	if (isp->otg->state != OTG_STATE_B_IDLE)
		return;

	/* disable data pullups */
	if (isp->otg->gadget)
		usb_gadget_disconnect(isp->otg->gadget);

	/* detect charger */
	detect = isp1704_charger_detect(isp);
	if (detect) {
		isp->present = detect;
		power_supply_changed(&isp->psy);
	}

	/* enable data pullups */
	if (isp->otg->gadget)
		usb_gadget_connect(isp->otg->gadget);
}
示例#3
0
static int g_dnl_unbind(struct usb_composite_dev *cdev)
{
	struct usb_gadget *gadget = cdev->gadget;

	debug("%s: calling usb_gadget_disconnect for "
			"controller '%s'\n", shortname, gadget->name);
	usb_gadget_disconnect(gadget);

	return 0;
}
示例#4
0
文件: core.c 项目: RyanAM/gs5-kernel
static void sec_reconnect_work(struct work_struct *data)
{
	struct dwc3 *udc = container_of(data, struct dwc3, reconnect_work);

	usb_gadget_disconnect(&udc->gadget);
	printk(KERN_ERR"usb: Disconnected in case of Super speed support \n");
	mdelay(1);
	usb_gadget_connect(&udc->gadget);

}
示例#5
0
static int __exit nokia_unbind(struct usb_composite_dev *cdev)
{
	gphonet_cleanup();
	gserial_cleanup();
	gether_cleanup();
//                                                 
	usb_gadget_disconnect(cdev->gadget);
//                                                 

	return 0;
}
示例#6
0
文件: g_dnl.c 项目: khadas/u-boot
static int g_dnl_unbind(struct usb_composite_dev *cdev)
{
	struct usb_gadget *gadget = cdev->gadget;

	free(cdev->config);
	cdev->config = NULL;
	debug("%s: calling usb_gadget_disconnect for "
			"controller '%s'\n", __func__, gadget->name);
	usb_gadget_disconnect(gadget);

	return 0;
}
示例#7
0
static void tegra_change_otg_state(struct tegra_otg_data *tegra,
				enum usb_otg_state to)
{
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;

	if(!tegra->interrupt_mode){
		DBG("OTG: Vbus detection is disabled");
		return;
	}

	DBG("%s(%d) requested otg state %s-->%s\n", __func__,
		__LINE__, tegra_state_name(from), tegra_state_name(to));

	if (to != OTG_STATE_UNDEFINED && from != to) {
		otg->state = to;
		/*dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));*/
		USBH_INFO("%s --> %s\n", tegra_state_name(from), tegra_state_name(to));

		if (from == OTG_STATE_A_SUSPEND) {
			if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) {
				usb_gadget_vbus_connect(otg->gadget);
#ifdef CONFIG_USB_ANDROID_PROJECTOR
				if (check_htc_mode_status() != NOT_ON_AUTOBOT) {
					htc_mode_enable(0);
					android_switch_default();
				}
#endif
			} else if (to == OTG_STATE_A_HOST) {
				tegra_start_host(tegra);
				dump_otg_state();
			}
		} else if (from == OTG_STATE_A_HOST) {
			if (to == OTG_STATE_A_SUSPEND)
				tegra_stop_host(tegra);
		} else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (to == OTG_STATE_A_SUSPEND)
				usb_gadget_vbus_disconnect(otg->gadget);
		}
	} else if (to != OTG_STATE_UNDEFINED && from == to) {
		USBH_INFO("%s --> %s (%d)\n", tegra_state_name(from), tegra_state_name(to), USB_disabled);
		if (USB_disabled) {
			usb_gadget_disconnect(otg->gadget);
		} else if (to == OTG_STATE_B_PERIPHERAL) {
			usb_gadget_vbus_connect(otg->gadget);
			usb_gadget_connect(otg->gadget);
		} else {
			usb_gadget_connect(otg->gadget);
		}
	}
}
示例#8
0
void usb_composite_force_reset(struct usb_composite_dev *cdev)
{
	unsigned long			flags;

	spin_lock_irqsave(&cdev->lock, flags);
	/* force reenumeration */
	if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) {
		spin_unlock_irqrestore(&cdev->lock, flags);

		usb_gadget_disconnect(cdev->gadget);
		msleep(10);
		usb_gadget_connect(cdev->gadget);
	} else {
		spin_unlock_irqrestore(&cdev->lock, flags);
	}
}
示例#9
0
void usb_composite_force_reset(struct usb_composite_dev *cdev)
{
	unsigned long                   flags;

	spin_lock_irqsave(&cdev->lock, flags);
	/* force reenumeration */
	if (cdev && cdev->gadget) {
		/* avoid sending a disconnect switch event until after we disconnect */
		cdev->mute_switch = 1;
		spin_unlock_irqrestore(&cdev->lock, flags);

		usb_gadget_disconnect(cdev->gadget);
		msleep(10);
		usb_gadget_connect(cdev->gadget);
	} else {
		spin_unlock_irqrestore(&cdev->lock, flags);
	}
}
示例#10
0
void usb_composite_force_reset(struct usb_composite_dev *cdev)
{
	unsigned long			flags;

	spin_lock_irqsave(&cdev->lock, flags);
	/* force reenumeration */
	if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) {
		spin_unlock_irqrestore(&cdev->lock, flags);

#ifdef FEATURE_ANDROID_PANTECH_USB_QC_FIX_BUG
        cdev->mute_switch = 1; 
#endif
		usb_gadget_disconnect(cdev->gadget);
		msleep(10);
		usb_gadget_connect(cdev->gadget);
	} else {
		spin_unlock_irqrestore(&cdev->lock, flags);
	}
}
示例#11
0
void usb_composite_force_reset(struct usb_composite_dev *cdev)
{
    unsigned long			flags;

    spin_lock_irqsave(&cdev->lock, flags);
    /* force reenumeration */
    if (cdev && cdev->gadget &&
            cdev->gadget->speed != USB_SPEED_UNKNOWN) {
        /* avoid sending a disconnect switch event until after we disconnect */
//		cdev->mute_switch = 1;// yk 20110505 rk29 don't need to mute switch
        spin_unlock_irqrestore(&cdev->lock, flags);

        usb_gadget_disconnect(cdev->gadget);
        msleep(10);
        usb_gadget_connect(cdev->gadget);
    } else {
        spin_unlock_irqrestore(&cdev->lock, flags);
    }
}
示例#12
0
void usb_composite_force_reset(struct usb_composite_dev *cdev)
{
	unsigned long			flags;

	spin_lock_irqsave(&cdev->lock, flags);
	/* force reenumeration */
	if (cdev && cdev->gadget &&
			cdev->gadget->speed != USB_SPEED_UNKNOWN) {
		/* avoid sending a disconnect switch event until after we disconnect */
		cdev->mute_switch = 1;
		spin_unlock_irqrestore(&cdev->lock, flags);
		CSY_DBG_ESS("disconnect usb\n");
		usb_gadget_disconnect(cdev->gadget);
		msleep(20);
		CSY_DBG_ESS("connect usb again\n");
		usb_gadget_connect(cdev->gadget);
	} else {
		CSY_DBG_ESS("skip reset\n");
		spin_unlock_irqrestore(&cdev->lock, flags);
	}
}
void usb_composite_force_reset(struct usb_composite_dev *cdev)
{
	unsigned long			flags;
	if (!cdev) {
		printk(KERN_ERR "usb_composite_force_reset: invalid cdev\n");
		return;
	}
	spin_lock_irqsave(&cdev->lock, flags);
	/* force reenumeration */
	if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) {
		spin_unlock_irqrestore(&cdev->lock, flags);
		/* avoid sending a disconnect switch event
		 * until after we disconnect
		 */
		cdev->mute_switch = 1;

		usb_gadget_disconnect(cdev->gadget);
		msleep(10);
		usb_gadget_connect(cdev->gadget);
	} else {
		spin_unlock_irqrestore(&cdev->lock, flags);
	}
}
示例#14
0
static void tegra_otg_shutdown(struct device *dev)
{
	DBG("%s(%d) BEGIN\n", __func__, __LINE__);
	struct otg_transceiver *otg = &tegra_clone->otg;
	usb_gadget_disconnect(otg->gadget);
}
示例#15
0
static void isp1704_charger_work(struct work_struct *data)
{
	int			detect;
	unsigned long		event;
	unsigned		power;
	struct isp1704_charger	*isp =
		container_of(data, struct isp1704_charger, work);
	static DEFINE_MUTEX(lock);

	event = isp->event;
	power = isp->max_power;

	mutex_lock(&lock);

	if (event != USB_EVENT_NONE)
		isp1704_charger_set_power(isp, 1);

	switch (event) {
	case USB_EVENT_VBUS:
		isp->online = true;

		/* detect charger */
		detect = isp1704_charger_detect(isp);

		if (detect) {
			isp->present = detect;
			isp->psy.type = isp1704_charger_type(isp);
		}

		switch (isp->psy.type) {
		case POWER_SUPPLY_TYPE_USB_DCP:
			isp->current_max = 1800;
			break;
		case POWER_SUPPLY_TYPE_USB_CDP:
			/*
			 * Only 500mA here or high speed chirp
			 * handshaking may break
			 */
			isp->current_max = 500;
			/* FALLTHROUGH */
		case POWER_SUPPLY_TYPE_USB:
		default:
			/* enable data pullups */
			if (isp->phy->otg->gadget)
				usb_gadget_connect(isp->phy->otg->gadget);
		}
		break;
	case USB_EVENT_NONE:
		isp->online = false;
		isp->current_max = 0;
		isp->present = 0;
		isp->current_max = 0;
		isp->psy.type = POWER_SUPPLY_TYPE_USB;

		/*
		 * Disable data pullups. We need to prevent the controller from
		 * enumerating.
		 *
		 * FIXME: This is here to allow charger detection with Host/HUB
		 * chargers. The pullups may be enabled elsewhere, so this can
		 * not be the final solution.
		 */
		if (isp->phy->otg->gadget)
			usb_gadget_disconnect(isp->phy->otg->gadget);

		isp1704_charger_set_power(isp, 0);
		break;
	case USB_EVENT_ENUMERATED:
		if (isp->present)
			isp->current_max = 1800;
		else
			isp->current_max = power;
		break;
	default:
		goto out;
	}

	power_supply_changed(&isp->psy);
out:
	mutex_unlock(&lock);
}
示例#16
0
static int __devinit isp1704_charger_probe(struct platform_device *pdev)
{
	struct isp1704_charger	*isp;
	int			ret = -ENODEV;

	isp = kzalloc(sizeof *isp, GFP_KERNEL);
	if (!isp)
		return -ENOMEM;

	isp->phy = usb_get_phy();
	if (!isp->phy)
		goto fail0;

	isp->dev = &pdev->dev;
	platform_set_drvdata(pdev, isp);

	isp1704_charger_set_power(isp, 1);

	ret = isp1704_test_ulpi(isp);
	if (ret < 0)
		goto fail1;

	isp->psy.name		= "isp1704";
	isp->psy.type		= POWER_SUPPLY_TYPE_USB;
	isp->psy.properties	= power_props;
	isp->psy.num_properties	= ARRAY_SIZE(power_props);
	isp->psy.get_property	= isp1704_charger_get_property;

	ret = power_supply_register(isp->dev, &isp->psy);
	if (ret)
		goto fail1;

	/*
	 * REVISIT: using work in order to allow the usb notifications to be
	 * made atomically in the future.
	 */
	INIT_WORK(&isp->work, isp1704_charger_work);

	isp->nb.notifier_call = isp1704_notifier_call;

	ret = usb_register_notifier(isp->phy, &isp->nb);
	if (ret)
		goto fail2;

	dev_info(isp->dev, "registered with product id %s\n", isp->model);

	/*
	 * Taking over the D+ pullup.
	 *
	 * FIXME: The device will be disconnected if it was already
	 * enumerated. The charger driver should be always loaded before any
	 * gadget is loaded.
	 */
	if (isp->phy->otg->gadget)
		usb_gadget_disconnect(isp->phy->otg->gadget);

	/* Detect charger if VBUS is valid (the cable was already plugged). */
	ret = isp1704_read(isp, ULPI_USB_INT_STS);
	isp1704_charger_set_power(isp, 0);
	if ((ret & ULPI_INT_VBUS_VALID) && !isp->phy->otg->default_a) {
		isp->event = USB_EVENT_VBUS;
		schedule_work(&isp->work);
	}

	return 0;
fail2:
	power_supply_unregister(&isp->psy);
fail1:
	usb_put_phy(isp->phy);
fail0:
	kfree(isp);

	dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret);

	isp1704_charger_set_power(isp, 0);
	return ret;
}
示例#17
0
static void isp1704_charger_work(struct work_struct *data)
{
	struct isp1704_charger	*isp =
		container_of(data, struct isp1704_charger, work);
	static DEFINE_MUTEX(lock);

	mutex_lock(&lock);

	switch (isp->phy->last_event) {
	case USB_EVENT_VBUS:
		/* do not call wall charger detection more times */
		if (!isp->present) {
			isp->online = true;
			isp->present = 1;
			isp1704_charger_set_power(isp, 1);

			/* detect wall charger */
			if (isp1704_charger_detect_dcp(isp)) {
				isp->psy_desc.type = POWER_SUPPLY_TYPE_USB_DCP;
				isp->current_max = 1800;
			} else {
				isp->psy_desc.type = POWER_SUPPLY_TYPE_USB;
				isp->current_max = 500;
			}

			/* enable data pullups */
			if (isp->phy->otg->gadget)
				usb_gadget_connect(isp->phy->otg->gadget);
		}

		if (isp->psy_desc.type != POWER_SUPPLY_TYPE_USB_DCP) {
			/*
			 * Only 500mA here or high speed chirp
			 * handshaking may break
			 */
			if (isp->current_max > 500)
				isp->current_max = 500;

			if (isp->current_max > 100)
				isp->psy_desc.type = POWER_SUPPLY_TYPE_USB_CDP;
		}
		break;
	case USB_EVENT_NONE:
		isp->online = false;
		isp->present = 0;
		isp->current_max = 0;
		isp->psy_desc.type = POWER_SUPPLY_TYPE_USB;

		/*
		 * Disable data pullups. We need to prevent the controller from
		 * enumerating.
		 *
		 * FIXME: This is here to allow charger detection with Host/HUB
		 * chargers. The pullups may be enabled elsewhere, so this can
		 * not be the final solution.
		 */
		if (isp->phy->otg->gadget)
			usb_gadget_disconnect(isp->phy->otg->gadget);

		isp1704_charger_set_power(isp, 0);
		break;
	default:
		goto out;
	}

	power_supply_changed(isp->psy);
out:
	mutex_unlock(&lock);
}
示例#18
0
static int isp1704_charger_probe(struct platform_device *pdev)
{
	struct isp1704_charger	*isp;
	int			ret = -ENODEV;
	struct power_supply_config psy_cfg = {};

	struct isp1704_charger_data *pdata = dev_get_platdata(&pdev->dev);
	struct device_node *np = pdev->dev.of_node;

	if (np) {
		int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0);

		if (gpio < 0) {
			dev_err(&pdev->dev, "missing DT GPIO nxp,enable-gpio\n");
			return gpio;
		}

		pdata = devm_kzalloc(&pdev->dev,
			sizeof(struct isp1704_charger_data), GFP_KERNEL);
		if (!pdata) {
			ret = -ENOMEM;
			goto fail0;
		}
		pdata->enable_gpio = gpio;

		dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio);

		ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio,
					GPIOF_OUT_INIT_HIGH, "isp1704_reset");
		if (ret) {
			dev_err(&pdev->dev, "gpio request failed\n");
			goto fail0;
		}
	}

	if (!pdata) {
		dev_err(&pdev->dev, "missing platform data!\n");
		return -ENODEV;
	}


	isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
	if (!isp)
		return -ENOMEM;

	if (np)
		isp->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
	else
		isp->phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);

	if (IS_ERR(isp->phy)) {
		ret = PTR_ERR(isp->phy);
		dev_err(&pdev->dev, "usb_get_phy failed\n");
		goto fail0;
	}

	isp->dev = &pdev->dev;
	platform_set_drvdata(pdev, isp);

	isp1704_charger_set_power(isp, 1);

	ret = isp1704_test_ulpi(isp);
	if (ret < 0) {
		dev_err(&pdev->dev, "isp1704_test_ulpi failed\n");
		goto fail1;
	}

	isp->psy_desc.name		= "isp1704";
	isp->psy_desc.type		= POWER_SUPPLY_TYPE_USB;
	isp->psy_desc.properties	= power_props;
	isp->psy_desc.num_properties	= ARRAY_SIZE(power_props);
	isp->psy_desc.get_property	= isp1704_charger_get_property;

	psy_cfg.drv_data		= isp;

	isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg);
	if (IS_ERR(isp->psy)) {
		ret = PTR_ERR(isp->psy);
		dev_err(&pdev->dev, "power_supply_register failed\n");
		goto fail1;
	}

	/*
	 * REVISIT: using work in order to allow the usb notifications to be
	 * made atomically in the future.
	 */
	INIT_WORK(&isp->work, isp1704_charger_work);

	isp->nb.notifier_call = isp1704_notifier_call;

	ret = usb_register_notifier(isp->phy, &isp->nb);
	if (ret) {
		dev_err(&pdev->dev, "usb_register_notifier failed\n");
		goto fail2;
	}

	dev_info(isp->dev, "registered with product id %s\n", isp->model);

	/*
	 * Taking over the D+ pullup.
	 *
	 * FIXME: The device will be disconnected if it was already
	 * enumerated. The charger driver should be always loaded before any
	 * gadget is loaded.
	 */
	if (isp->phy->otg->gadget)
		usb_gadget_disconnect(isp->phy->otg->gadget);

	if (isp->phy->last_event == USB_EVENT_NONE)
		isp1704_charger_set_power(isp, 0);

	/* Detect charger if VBUS is valid (the cable was already plugged). */
	if (isp->phy->last_event == USB_EVENT_VBUS &&
			!isp->phy->otg->default_a)
		schedule_work(&isp->work);

	return 0;
fail2:
	power_supply_unregister(isp->psy);
fail1:
	isp1704_charger_set_power(isp, 0);
fail0:
	dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret);

	return ret;
}