예제 #1
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);
		}
	}
}
예제 #2
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);
	}
}
예제 #3
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);
}
예제 #4
0
파일: g_dnl.c 프로젝트: khadas/u-boot
static int g_dnl_bind(struct usb_composite_dev *cdev)
{
	struct usb_gadget *gadget = cdev->gadget;
	int id, ret;
	int gcnum;
	char *s=NULL;

	debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev);

	id = usb_string_id(cdev);

	if (id < 0)
		return id;
	g_dnl_string_defs[0].id = id;
	device_desc.iManufacturer = id;

	id = usb_string_id(cdev);
	if (id < 0)
		return id;

	g_dnl_string_defs[1].id = id;
	device_desc.iProduct = id;

	id = usb_string_id(cdev);
	if (id < 0)
		return id;

	g_dnl_string_defs[2].id = id;
	device_desc.iSerialNumber = id;

	s = get_usid_string();
	if (s)
		g_dnl_set_serialnumber(s);

	g_dnl_bind_fixup(&device_desc, cdev->driver->name);
	ret = g_dnl_config_register(cdev);
	if (ret)
		goto error;

	gcnum = g_dnl_get_bcd_device_number(cdev);
	if (gcnum >= 0)
		device_desc.bcdDevice = cpu_to_le16(gcnum);
	else {
		debug("%s: controller '%s' not recognized\n",
			__func__, gadget->name);
		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
	}

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

	return 0;

 error:
	g_dnl_unbind(cdev);
	return -ENOMEM;
}
예제 #5
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);

}
예제 #6
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);
	}
}
예제 #7
0
파일: composite.c 프로젝트: atarii/BDA-ACTV
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);
	}
}
예제 #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) {
        /* 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);
    }
}
예제 #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 && 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);
	}
}
예제 #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) {
		/* 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);
	}
}
예제 #12
0
파일: g_dnl.c 프로젝트: disdi/u-boot-cavium
static int g_dnl_config_register(struct usb_composite_dev *cdev)
{
	static struct usb_configuration config = {
		.label = "usb_dnload",
		.bmAttributes =	USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
		.bConfigurationValue =	CONFIG_USBDOWNLOADER,
		.iConfiguration =	STRING_USBDOWN,

		.bind = g_dnl_do_config,
	};

	return usb_add_config(cdev, &config);
}

__weak
int g_dnl_bind_fixup(struct usb_device_descriptor *dev)
{
	return 0;
}

static int g_dnl_bind(struct usb_composite_dev *cdev)
{
	struct usb_gadget *gadget = cdev->gadget;
	int id, ret;
	int gcnum;

	debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev);

	id = usb_string_id(cdev);

	if (id < 0)
		return id;
	g_dnl_string_defs[0].id = id;
	device_desc.iManufacturer = id;

	id = usb_string_id(cdev);
	if (id < 0)
		return id;

	g_dnl_string_defs[1].id = id;
	device_desc.iProduct = id;

	g_dnl_bind_fixup(&device_desc);
	ret = g_dnl_config_register(cdev);
	if (ret)
		goto error;

	gcnum = usb_gadget_controller_number(gadget);

	debug("gcnum: %d\n", gcnum);
	if (gcnum >= 0)
		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
	else {
		debug("%s: controller '%s' not recognized\n",
			shortname, gadget->name);
		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
	}

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

	return 0;

 error:
	g_dnl_unbind(cdev);
	return -ENOMEM;
}

static struct usb_composite_driver g_dnl_driver = {
	.name = NULL,
	.dev = &device_desc,
	.strings = g_dnl_composite_strings,

	.bind = g_dnl_bind,
	.unbind = g_dnl_unbind,
};

int g_dnl_register(const char *type)
{
	/* We only allow "dfu" atm, so 3 should be enough */
	static char name[sizeof(shortname) + 3];
	int ret;

	if (!strcmp(type, "dfu")) {
		strcpy(name, shortname);
		strcat(name, type);
	} else if (!strcmp(type, "ums")) {
		strcpy(name, shortname);
		strcat(name, type);
	} else {
		printf("%s: unknown command: %s\n", __func__, type);
		return -EINVAL;
	}

	g_dnl_driver.name = name;

	debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name);
	ret = usb_composite_register(&g_dnl_driver);

	if (ret) {
		printf("%s: failed!, error: %d\n", __func__, ret);
		return ret;
	}

	return 0;
}

void g_dnl_unregister(void)
{
	usb_composite_unregister(&g_dnl_driver);
}
예제 #13
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);
}
예제 #14
0
static int __init nokia_bind(struct usb_composite_dev *cdev)
{
	int			gcnum;
	struct usb_gadget	*gadget = cdev->gadget;
	int			status;

	printk("nokia_bind called!!!!\n");
	status = gphonet_setup(cdev->gadget);
	if (status < 0)
		goto err_phonet;

	status = gserial_setup(cdev->gadget, 3);
	if (status < 0)
		goto err_serial;

	status = gether_setup(cdev->gadget, hostaddr);
	if (status < 0)
		goto err_ether;

	status = usb_string_id(cdev);
	if (status < 0)
		goto err_usb;
	strings_dev[STRING_MANUFACTURER_IDX].id = status;

	device_desc.iManufacturer = status;

	status = usb_string_id(cdev);
	if (status < 0)
		goto err_usb;
	strings_dev[STRING_PRODUCT_IDX].id = status;

	device_desc.iProduct = status;

	/* config description */
	status = usb_string_id(cdev);
	if (status < 0)
		goto err_usb;
	strings_dev[STRING_DESCRIPTION_IDX].id = status;

	nokia_config_500ma_driver.iConfiguration = status;
	nokia_config_100ma_driver.iConfiguration = status;

	/* set up other descriptors */
	gcnum = usb_gadget_controller_number(gadget);
	if (gcnum >= 0)
		device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
	else {
		/* this should only work with hw that supports altsettings
		 * and several endpoints, anything else, panic.
		 */
		pr_err("nokia_bind: controller '%s' not recognized\n",
			gadget->name);
		goto err_usb;
	}

	/* finally register the configuration */
	status = usb_add_config(cdev, &nokia_config_500ma_driver,
			nokia_bind_config);
	if (status < 0)
		goto err_usb;

	status = usb_add_config(cdev, &nokia_config_100ma_driver,
			nokia_bind_config);
	if (status < 0)
		goto err_usb;
//                                                
	usb_gadget_connect(cdev->gadget);
//                                                
	dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);

	return 0;

err_usb:
	gether_cleanup();
err_ether:
	gserial_cleanup();
err_serial:
	gphonet_cleanup();
err_phonet:
	return status;
}
예제 #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);
}