static void cable2pc_detect_works(struct work_struct *work) { int usb_cable; static int reenum_cnt = REENUM_CNT; struct gadget_wrapper *d; d = gadget_wrapper; usb_cable = cable_is_usb(); /* in factory mode, we know the cable must be usb, so we enumerate * again */ if (in_factory_mode() && !usb_cable && reenum_cnt){ pr_info("try usb enumertation again\n"); reenum_cnt--; mutex_lock(&udc_lock); __udc_shutdown(); queue_delayed_work(d->cable2pc_wq, &d->cable2pc,CABLE_TIMEOUT); __udc_startup(); mutex_unlock(&udc_lock); return; } mutex_lock(&udc_lock); if (!usb_cable) { pr_info("cable is ac adapter\n"); __udc_shutdown(); } mutex_unlock(&udc_lock); return; }
static void cable_detect_handler(unsigned long data) { int usb_cable; static int reenum_cnt = REENUM_CNT; usb_cable = cable_is_usb(); /* in factory mode, we know the cable must be usb, so we enumerate * again */ if (in_factory_mode() && !usb_cable && reenum_cnt){ pr_info("try usb enumertation again\n"); reenum_cnt--; mutex_lock(&udc_lock); __udc_shutdown(); mod_timer(&gadget_wrapper->cable_timer, jiffies + CABLE_TIMEOUT); __udc_startup(); mutex_unlock(&udc_lock); return; } mutex_lock(&udc_lock); if (!usb_cable) { pr_info("cable is ac adapter\n"); __udc_shutdown(); } mutex_unlock(&udc_lock); return; }
static void usb_detect_works(struct work_struct *work) { struct gadget_wrapper *d; unsigned long flags; int plug_in; d = gadget_wrapper; spin_lock_irqsave(&d->lock, flags); plug_in = d->vbus; spin_unlock_irqrestore(&d->lock, flags); mutex_lock(&udc_lock); if (plug_in){ pr_info("usb detect plug in,vbus pull up\n"); hotplug_callback(VBUS_PLUG_IN, 0); if(get_usb_first_enable_store_flag()){ mod_timer(&d->cable_timer, jiffies + CABLE_TIMEOUT); __udc_startup(); } } else { pr_info("usb detect plug out,vbus pull down\n"); del_timer(&d->cable_timer); __udc_shutdown(); hotplug_callback(VBUS_PLUG_OUT, cable_is_usb()); } mutex_unlock(&udc_lock); switch_set_state(&d->sdev, !!plug_in); }
static int pullup(struct usb_gadget *gadget, int is_on) { struct gadget_wrapper *d; int action = is_on; #ifndef DWC_DEVICE_ONLY if(!usb_get_id_state()) return 0; #endif if (gadget == 0) return -ENODEV; else d = container_of(gadget, struct gadget_wrapper, gadget); d->softconnect = is_on; #ifdef CONFIG_USB_EXTERNAL_DETECT if (!d->enabled || !d->vbus) { printk("usb: %s, d->enable = %d, d->vbus=%d \r\n",__func__, d->enabled, d->vbus); return 0; } mutex_lock(&udc_lock); if (action) { __udc_startup(); } else { __udc_shutdown(); } mutex_unlock(&udc_lock); #else if (!d->enabled || !d->vbus) action = 0; mutex_lock(&udc_lock); if (action) { queue_delayed_work(d->cable2pc_wq, &d->cable2pc,CABLE_TIMEOUT); __udc_startup(); } else { /* *this is soft disconnct, and maybe the timer started *by plugin still work, need cancel this timer like plugout */ cancel_delayed_work_sync(&d->cable2pc); __udc_shutdown(); } mutex_unlock(&udc_lock); #endif return 0; }
static int pullup(struct usb_gadget *gadget, int is_on) { struct gadget_wrapper *d; int action = is_on; if (gadget == 0) return -ENODEV; else d = container_of(gadget, struct gadget_wrapper, gadget); if (is_on) { static int enum_enabled = 0; if (unlikely(!enum_enabled)) { enum_enabled = 1; enumeration_enable(); // return 0; } } if (!d->enabled || !d->vbus) action = 0; mutex_lock(&udc_lock); if (action) { mod_timer(&d->cable_timer, jiffies + CABLE_TIMEOUT); __udc_startup(); } else { /* *this is soft disconnct, and maybe the timer started *by plugin still work, need cancel this timer like plugout */ if(timer_pending(&d->cable_timer)) del_timer(&d->cable_timer); __udc_shutdown(); } mutex_unlock(&udc_lock); return 0; }
static int pullup(struct usb_gadget *gadget, int is_on) { struct gadget_wrapper *d; int action = is_on; #ifndef DWC_DEVICE_ONLY if(!usb_get_id_state()) return 0; #endif if (gadget == 0) return -ENODEV; else d = container_of(gadget, struct gadget_wrapper, gadget); #ifdef CONFIG_USB_INTERRUPT_BY_MUIC // need to check vbus again if (!d->enabled) action = 0; #else if (!d->enabled || !d->vbus) action = 0; #endif mutex_lock(&udc_lock); if (action) { queue_delayed_work(d->cable2pc_wq, &d->cable2pc,CABLE_TIMEOUT); __udc_startup(); } else { /* *this is soft disconnct, and maybe the timer started *by plugin still work, need cancel this timer like plugout */ cancel_delayed_work_sync(&d->cable2pc); __udc_shutdown(); } mutex_unlock(&udc_lock); return 0; }
/** * This function initialized the PCD portion of the driver. * */ int pcd_init( struct platform_device *_dev ) { dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev); int retval = 0; int irq; DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev); wake_lock_init(&usb_wake_lock, WAKE_LOCK_SUSPEND, "usb_work"); otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if); if (!otg_dev->pcd) { DWC_ERROR("dwc_otg_pcd_init failed\n"); return -ENOMEM; } gadget_wrapper = alloc_wrapper(_dev); /* * Initialize EP structures */ gadget_add_eps(gadget_wrapper); /* * Setup interupt handler */ irq = platform_get_irq(_dev, 0); DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq); retval = request_irq(irq, dwc_otg_pcd_irq, 0, gadget_wrapper->gadget.name, otg_dev->pcd); //SA_SHIRQ, gadget_wrapper->gadget.name, if (retval != 0) { DWC_ERROR("request of irq%d failed\n", irq); free_wrapper(gadget_wrapper); return -EBUSY; } /* * initialize a timer for checking cable type. */ { setup_timer(&setup_transfer_timer,setup_transfer_timer_fun,(unsigned long)gadget_wrapper); setup_transfer_timer_start = 0; } setup_timer(&gadget_wrapper->cable_timer, cable_detect_handler, (unsigned long)gadget_wrapper); /* * setup usb cable detect interupt */ { int plug_irq; plug_irq = usb_alloc_vbus_irq(); if (plug_irq < 0) { pr_warning("cannot alloc vbus irq\n"); return -EBUSY; } usb_set_vbus_irq_type(plug_irq, VBUS_PLUG_IN); gadget_wrapper->vbus = usb_get_vbus_state(); pr_info("now usb vbus is :%d\n", gadget_wrapper->vbus); retval = request_irq(plug_irq, usb_detect_handler, IRQF_SHARED, "usb detect", otg_dev->pcd); } spin_lock_init(&gadget_wrapper->lock); INIT_WORK(&gadget_wrapper->detect_work, usb_detect_works); gadget_wrapper->detect_wq = create_singlethread_workqueue("usb detect wq"); /* * register a switch device for sending pnp message, * for the user app need be notified immediately * when plug in & plug out happen; */ gadget_wrapper->sdev.name = "charger_cable"; retval = switch_dev_register(&gadget_wrapper->sdev); if (retval){ pr_warning("register switch dev error:%s\n", __func__); } dwc_otg_pcd_start(gadget_wrapper->pcd, &fops); /* * dwc driver is ok, check if the cable is insert, if no, * shutdown udc for saving power. */ if (!gadget_wrapper->vbus){ pr_debug("vbus is not power now \n"); gadget_wrapper->udc_startup = 1; __udc_shutdown(); } gadget_wrapper->udc_startup = gadget_wrapper->vbus; gadget_wrapper->enabled = 0; return retval; }
void dwc_udc_shutdown(void) { mutex_lock(&udc_lock); __udc_shutdown(); mutex_unlock(&udc_lock); }
/** * This function initialized the PCD portion of the driver. * */ int pcd_init( struct platform_device *_dev ) { dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev); struct sprd_usb_platform_data *pdata= _dev->dev.platform_data; int retval = 0; int irq; int plug_irq; DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev); device_dwc_otg = &(_dev->dev); if (dwc_otg_is_dma_enable(otg_dev->core_if)) { _dev->dev.dma_mask = &dwc_otg_pcd_dmamask; _dev->dev.coherent_dma_mask = dwc_otg_pcd_dmamask; } else { _dev->dev.dma_mask = (void *)0; _dev->dev.coherent_dma_mask = 0; } wake_lock_init(&usb_wake_lock, WAKE_LOCK_SUSPEND, "usb_work"); // wake_lock(&usb_wake_lock); otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if); if (!otg_dev->pcd) { DWC_ERROR("dwc_otg_pcd_init failed\n"); return -ENOMEM; } gadget_wrapper = alloc_wrapper(_dev); /* * Initialize EP structures */ gadget_add_eps(gadget_wrapper); /* * Setup interupt handler */ irq = platform_get_irq(_dev, 0); DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq); retval = request_irq(irq, dwc_otg_pcd_irq, IRQF_SHARED, gadget_wrapper->gadget.name, otg_dev->pcd); //SA_SHIRQ, gadget_wrapper->gadget.name, if (retval != 0) { DWC_ERROR("request of irq%d failed\n", irq); free_wrapper(gadget_wrapper); return -EBUSY; } /* * initialize a timer for checking cable type. */ #ifdef USB_SETUP_TIMEOUT_RESTART { setup_timer(&setup_transfer_timer, setup_transfer_timer_fun, (unsigned long)gadget_wrapper); setup_transfer_timer_start = 0; } #endif INIT_DELAYED_WORK(&gadget_wrapper->cable2pc, cable2pc_detect_works); gadget_wrapper->cable2pc_wq = create_singlethread_workqueue("usb 2 pc wq"); #ifdef CONFIG_USB_EXTERNAL_DETECT register_otg_func(NULL, dwc_peripheral_start, otg_dev); #else /* * setup usb cable detect interupt */ #ifndef CONFIG_MFD_SM5504 { plug_irq = usb_alloc_vbus_irq(pdata->gpio_chgdet); if (plug_irq < 0) { pr_warning("cannot alloc vbus irq\n"); return -EBUSY; } usb_set_vbus_irq_type(plug_irq, VBUS_PLUG_IN); #ifdef CONFIG_SC_FPGA gadget_wrapper->vbus = 1; #else gadget_wrapper->vbus = usb_get_vbus_state(); #endif pr_info("now usb vbus is :%d\n", gadget_wrapper->vbus); retval = request_irq(plug_irq, usb_detect_handler, IRQF_SHARED | IRQF_NO_SUSPEND, "usb detect", otg_dev->pcd); #ifndef CONFIG_MUIC_CABLE_DETECT disable_irq(plug_irq); #endif } //gadget_wrapper->vbus = 1;//used when debug in FPGA, which doesn't have vbus operation #endif spin_lock_init(&gadget_wrapper->lock); #ifdef CONFIG_SC_FPGA gadget_wrapper->vbus = 1; #endif INIT_WORK(&gadget_wrapper->detect_work, usb_detect_works); gadget_wrapper->detect_wq = create_singlethread_workqueue("usb detect wq"); #endif /* * register a switch device for sending pnp message, * for the user app need be notified immediately * when plug in & plug out happen; */ gadget_wrapper->sdev.name = "charger_cable"; retval = switch_dev_register(&gadget_wrapper->sdev); if (retval){ pr_warning("register switch dev error:%s\n", __func__); } dwc_otg_pcd_start(gadget_wrapper->pcd, &fops); /* * dwc driver is ok, check if the cable is insert, if no, * shutdown udc for saving power. */ if (!gadget_wrapper->vbus){ pr_debug("vbus is not power now \n"); gadget_wrapper->udc_startup = 1; __udc_shutdown(); } gadget_wrapper->udc_startup = gadget_wrapper->vbus; gadget_wrapper->enabled = 0; retval = usb_add_gadget_udc(&_dev->dev, &gadget_wrapper->gadget); if (!retval) return retval; return retval; }