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); } } }
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); } }
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); }
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; }
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); }
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); } }
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); } }
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); } }
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); } }
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); } }
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); }
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); }
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; }
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); }