static void msm_otg_power_work(struct work_struct *w) { struct msm_otg *motg = container_of(w, struct msm_otg, otg_power_work); int otg_test = gpio_get_value_cansleep(motg->pdata->otg_test_gpio); msleep(200); pr_info("id: %d, otg_test: %d\n", test_bit(ID, &motg->inputs), otg_test); /* host */ if (!test_bit(ID, &motg->inputs)) { if (otg_test) { motg->ndev.booster = NOTIFY_POWER_ON; } else { motg->ndev.booster = NOTIFY_POWER_OFF; host_state_notify(&motg->ndev, NOTIFY_HOST_OVERCURRENT); pr_err("OTG Overcurrent!\n"); } } else { if (motg->ndev.mode == NOTIFY_HOST_MODE && otg_test == 0) motg->ndev.booster = NOTIFY_POWER_OFF; } }
static irqreturn_t host_notifier_currentlimit_irq_thread (int irq, void *data) { unsigned long flags = 0; int gpio_value = 0; spin_lock_irqsave(&ninfo.vbus_gpio.lock, flags); if (ninfo.pdata->inverse_vbus_trigger) gpio_value = !ninfo.vbus_gpio.gpio_status ; else gpio_value = ninfo.vbus_gpio.gpio_status ; spin_unlock_irqrestore(&ninfo.vbus_gpio.lock, flags); if (gpio_value) { ninfo.pdata->ndev.booster = NOTIFY_POWER_ON; pr_info("Acc power on detect\n"); } else { if ((ninfo.pdata->ndev.mode == NOTIFY_HOST_MODE) && (ninfo.pdata->ndev.booster == NOTIFY_POWER_ON)) { host_state_notify(&ninfo.pdata->ndev, NOTIFY_HOST_OVERCURRENT); pr_err("OTG overcurrent!!!!!!\n"); } ninfo.pdata->ndev.booster = NOTIFY_POWER_OFF; } return IRQ_HANDLED; }
static irqreturn_t currentlimit_irq_thread(int irq, void *data) { struct host_notifier_info *hostinfo = data; struct host_notify_dev *ndev = &hostinfo->pdata->ndev; int gpio = hostinfo->pdata->gpio; int prev = ndev->booster; int ret = 0; ret = gpio_get_value(gpio); pr_info("currentlimit_irq_thread gpio : %d, value : %d\n", gpio, ret); if (prev != ret) { pr_info("host_notifier currentlimit_irq_thread: gpio %d = %s\n", gpio, ret ? "HIGH" : "LOW"); ndev->booster = ret ? NOTIFY_POWER_ON : NOTIFY_POWER_OFF; prev = ret; if (!ret && ndev->mode == NOTIFY_HOST_MODE) { host_state_notify(ndev, NOTIFY_HOST_OVERCURRENT); pr_err("host_notifier currentlimit_irq_thread: overcurrent\n"); } } return IRQ_HANDLED; }
static int currentlimit_thread(void *data) { struct host_notifier_info *ninfo = data; struct host_notify_dev *ndev = &ninfo->pdata->ndev; int gpio = ninfo->pdata->gpio; int prev = ndev->booster; int ret = 0; pr_info("host_notifier usbhostd: start %d\n", prev); while (!kthread_should_stop()) { wait_event_interruptible_timeout(ninfo->delay_wait, ninfo->thread_remove, 1 * HZ); ret = gpio_get_value(gpio); if (prev != ret) { pr_info("host_notifier usbhostd: gpio %d = %s\n", gpio, ret ? "HIGH" : "LOW"); ndev->booster = ret ? NOTIFY_POWER_ON : NOTIFY_POWER_OFF; prev = ret; if (!ret && ndev->mode == NOTIFY_HOST_MODE) { host_state_notify(ndev, NOTIFY_HOST_OVERCURRENT); pr_err("host_notifier usbhostd: overcurrent\n"); break; } } } ninfo->thread_remove = 1; pr_info("host_notifier usbhostd: exit %d\n", ret); return 0; }
static int ovc_scan_thread(void *data) { struct ovc *ovcinfo = NULL; int state; if (!u_notify) { pr_err("%s u_notify is NULL\n", __func__); return 0; } ovcinfo = &u_notify->ovc_info; while (!kthread_should_stop()) { wait_event_interruptible_timeout(ovcinfo->delay_wait, ovcinfo->thread_remove, (ovcinfo->poll_period)*HZ); if (ovcinfo->thread_remove) break; mutex_lock(&u_notify->ovc_info.ovc_lock); if (ovcinfo->check_state && ovcinfo->data && ovcinfo->can_ovc) { state = ovcinfo->check_state(data); if (ovcinfo->prev_state != state) { if (state == HNOTIFY_LOW) { pr_err("%s overcurrent detected\n", __func__); host_state_notify(&u_notify->ndev, NOTIFY_HOST_OVERCURRENT); } else if (state == HNOTIFY_HIGH) { pr_info("%s vbus draw detected\n", __func__); host_state_notify(&u_notify->ndev, NOTIFY_HOST_NONE); } } ovcinfo->prev_state = state; } mutex_unlock(&u_notify->ovc_info.ovc_lock); if (!ovcinfo->can_ovc) ovcinfo->thread_remove = 1; } pr_info("ovc_scan_thread exit\n"); complete_and_exit(&ovcinfo->scanning_done, 0); return 0; }
static int start_usbhostd_notify(void) { pr_info("host_notifier: start usbhostd notify\n"); host_state_notify(&ninfo.pdata->ndev, NOTIFY_HOST_ADD); wake_lock(&ninfo.wlock); return 0; }
static int stop_usbhostd_notify(void) { pr_info("host_notifier: stop usbhostd notify\n"); host_state_notify(&ninfo.pdata->ndev, NOTIFY_HOST_REMOVE); wake_unlock(&ninfo.wlock); return 0; }
static void msm_otg_host_notify(struct msm_otg *motg, int on) { pr_info("host_notify: %d, dock %d\n", on, motg->smartdock); if (on) msm_otg_host_phy_tune(motg, 0x33, 0x14); if (motg->smartdock) { motg->ndev.state = NOTIFY_HOST_REMOVE; return; } if (on) { motg->ndev.mode = NOTIFY_HOST_MODE; host_state_notify(&motg->ndev, NOTIFY_HOST_ADD); } else { motg->ndev.mode = NOTIFY_NONE_MODE; host_state_notify(&motg->ndev, NOTIFY_HOST_REMOVE); } }
static int start_usbhostd_notify(void) { pr_info("host_notifier: start usbhostd notify\n"); #ifdef CONFIG_MACH_P4NOTE host_notifier_enable_irq(); #endif host_state_notify(&ninfo.pdata->ndev, NOTIFY_HOST_ADD); wake_lock(&ninfo.wlock); return 0; }
static int stop_usbhostd_notify(void) { pr_info("host_notifier: stop usbhostd notify\n"); #ifdef CONFIG_MACH_P4NOTE host_notifier_disable_irq(); #endif host_state_notify(&ninfo.pdata->ndev, NOTIFY_HOST_REMOVE); wake_unlock(&ninfo.wlock); return 0; }
static int stop_usbhostd_thread(void) { if (ninfo.th) { pr_info("host_notifier: stop thread\n"); if (!ninfo.thread_remove) kthread_stop(ninfo.th); ninfo.th = NULL; host_state_notify(&ninfo.pdata->ndev, NOTIFY_HOST_REMOVE); wake_unlock(&ninfo.wlock); } else pr_info("host_notifier: no thread\n"); return 0; }
static void otg_power_work(struct work_struct *work) { struct sec_otghost *otghost = container_of(work, struct sec_otghost, work); struct sec_otghost_data *hdata = otghost->otg_data; if (hdata && hdata->set_pwr_cb) { pr_info("otg power off - don't turn off the power\n"); hdata->set_pwr_cb(0); #ifdef CONFIG_USB_HOST_NOTIFY if (g_pUsbHcd) host_state_notify(&g_pUsbHcd->ndev, NOTIFY_HOST_OVERCURRENT); #endif } else { otg_err(true, "invalid otghost data\n"); } }
static int currentlimit_thread(void *data) { struct host_notifier_info *ninfo = data; struct host_notify_dev *ndev = &ninfo->pdata->ndev; int gpio = ninfo->pdata->gpio; int count = 0; int ret = 0; pr_info("host_notifier usbhostd: start mode %d\n", ndev->mode); ndev->booster = NOTIFY_POWER_ON; while (!kthread_should_stop()) { wait_event_interruptible_timeout(ninfo->delay_wait, ninfo->thread_remove, 1 * HZ); ret = gpio_get_value(gpio); if ((count++ % 10) == 0) { pr_info("host_notifier usbhostd: mode %d, count %d, %s\n", ndev->mode, count, ret ? "HIGH" : "LOW"); } if (!ret) { pr_info("host_notifier usbhostd: mode %d, count %d, (%d, %d)\n", ndev->mode, count, ndev->booster, ret); ndev->booster = NOTIFY_POWER_OFF; if (ndev->mode == NOTIFY_HOST_MODE) { host_state_notify(ndev, NOTIFY_HOST_OVERCURRENT); pr_err("host_notifier usbhostd: overcurrent\n"); break; } } } ninfo->thread_remove = 1; pr_info("host_notifier usbhostd: exit %d\n", ret); return 0; }
static irqreturn_t tegra_currentlimit_irq_thread(int irq, void *data) { struct tegra_otg_data *tegra = data; if (tegra_get_accpower_level(tegra->currentlimit_irq)) { #ifdef CONFIG_USB_HOST_NOTIFY tegra->ndev.booster = NOTIFY_POWER_ON; #endif dev_info(tegra->otg.dev, "Acc power on detect\n"); } else { #ifdef CONFIG_USB_HOST_NOTIFY if (tegra->ndev.mode == NOTIFY_HOST_MODE) { host_state_notify(&tegra->ndev, NOTIFY_HOST_OVERCURRENT, false); dev_err(tegra->otg.dev, "OTG overcurrent!!!!!!\n"); } tegra->ndev.booster = NOTIFY_POWER_OFF; #endif } return IRQ_HANDLED; }
static void msm_otg_notify_work(struct work_struct *w) { struct msm_otg *motg = container_of(w, struct msm_otg, notify_work); if (motg->smartdock) return; switch (motg->notify_state) { case ACC_POWER_ON: dev_info(motg->phy.dev, "Acc power on detect\n"); break; case ACC_POWER_OFF: dev_info(motg->phy.dev, "Acc power off detect\n"); break; case ACC_POWER_OVER_CURRENT: host_state_notify(&motg->ndev, NOTIFY_HOST_OVERCURRENT); dev_err(motg->phy.dev, "OTG overcurrent!!!!!!\n"); break; default: break; } }
static irqreturn_t vbus_irq_thread(int irq, void *data) { struct otg_notify *notify = NULL; unsigned long flags = 0; int gpio_value = 0; if (!u_notify) { pr_err("u_notify is NULL\n"); return IRQ_HANDLED; } notify = u_notify->o_notify; spin_lock_irqsave(&u_notify->v_gpio.lock, flags); gpio_value = u_notify->v_gpio.gpio_status; spin_unlock_irqrestore(&u_notify->v_gpio.lock, flags); if (gpio_value) { u_notify->ndev.booster = NOTIFY_POWER_ON; pr_info("vbus on detect\n"); if (notify->post_vbus_detect) notify->post_vbus_detect(NOTIFY_POWER_ON); } else { if ((u_notify->ndev.mode == NOTIFY_HOST_MODE) && (u_notify->ndev.booster == NOTIFY_POWER_ON && u_notify->oc_noti)) { host_state_notify(&u_notify->ndev, NOTIFY_HOST_OVERCURRENT); pr_err("OTG overcurrent!!!!!!\n"); } else { pr_info("vbus off detect\n"); if (notify->post_vbus_detect) notify->post_vbus_detect(NOTIFY_POWER_OFF); } u_notify->ndev.booster = NOTIFY_POWER_OFF; } return IRQ_HANDLED; }
static int start_usbhostd_thread(void) { if (!ninfo.th) { pr_info("host_notifier: start usbhostd thread\n"); init_waitqueue_head(&ninfo.delay_wait); ninfo.thread_remove = 0; ninfo.th = kthread_run(currentlimit_thread, &ninfo, "usbhostd"); if (IS_ERR(ninfo.th)) { pr_err("host_notifier: Unable to start usbhostd\n"); ninfo.th = NULL; ninfo.thread_remove = 1; return -1; } host_state_notify(&ninfo.pdata->ndev, NOTIFY_HOST_ADD); wake_lock(&ninfo.wlock); } else pr_info("host_notifier: usbhostd already started!\n"); return 0; }
static void irq_work(struct work_struct *work) { struct tegra_otg_data *tegra = container_of(work, struct tegra_otg_data, work); struct otg_transceiver *otg = &tegra->otg; enum usb_otg_state from = otg->state; enum usb_otg_state to = OTG_STATE_UNDEFINED; unsigned long flags; unsigned long status; if (tegra->detect_vbus) { tegra->detect_vbus = false; tegra_otg_enable_clk(); return; } clk_enable(tegra->clk); spin_lock_irqsave(&tegra->lock, flags); status = tegra->int_status; /* Debug prints */ DBG("%s(%d) status = 0x%x\n", __func__, __LINE__, status); if ((status & USB_ID_INT_STATUS) && (status & USB_VBUS_INT_STATUS)) DBG("%s(%d) got vbus & id interrupt\n", __func__, __LINE__); else { if (status & USB_ID_INT_STATUS) DBG("%s(%d) got id interrupt\n", __func__, __LINE__); if (status & USB_VBUS_INT_STATUS) DBG("%s(%d) got vbus interrupt\n", __func__, __LINE__); } if (tegra->int_status & USB_ID_INT_STATUS) { if (status & USB_ID_STATUS) { if ((status & USB_VBUS_STATUS) && (from != OTG_STATE_A_HOST)) to = OTG_STATE_B_PERIPHERAL; else to = OTG_STATE_A_SUSPEND; } else to = OTG_STATE_A_HOST; } if (from != OTG_STATE_A_HOST) { if (tegra->int_status & USB_VBUS_INT_STATUS) { if (status & USB_VBUS_STATUS) to = OTG_STATE_B_PERIPHERAL; else to = OTG_STATE_A_SUSPEND; } } spin_unlock_irqrestore(&tegra->lock, flags); if (to != OTG_STATE_UNDEFINED) { otg->state = to; dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from), tegra_state_name(to)); if (tegra->charger_cb) tegra->charger_cb(to, from, tegra->charger_cb_data); if (to == OTG_STATE_A_SUSPEND) { #ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA #ifdef CONFIG_USB_HOST_NOTIFY tegra->ndev.mode = NOTIFY_NONE_MODE; #endif #endif if (from == OTG_STATE_A_HOST) { #ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA #ifdef CONFIG_USB_HOST_NOTIFY host_state_notify(&tegra->ndev, NOTIFY_HOST_REMOVE, false); #endif #endif tegra_stop_host(tegra); } else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) #ifdef _SEC_DM_ if (!usb_access_lock) #endif usb_gadget_vbus_disconnect(otg->gadget); } else if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) { if (from != OTG_STATE_B_PERIPHERAL) #ifdef _SEC_DM_ if (!usb_access_lock) #endif usb_gadget_vbus_connect(otg->gadget); #ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA #ifdef CONFIG_USB_HOST_NOTIFY tegra->ndev.mode = NOTIFY_PERIPHERAL_MODE; #endif #endif } else if (to == OTG_STATE_A_HOST) { if (from == OTG_STATE_A_SUSPEND) tegra_start_host(tegra); #ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA else if (from == OTG_STATE_B_PERIPHERAL) { #ifdef _SEC_DM_ if (!usb_access_lock) #endif usb_gadget_vbus_disconnect(otg->gadget); tegra_start_host(tegra); } #ifdef CONFIG_USB_HOST_NOTIFY tegra->ndev.mode = NOTIFY_HOST_MODE; host_state_notify(&tegra->ndev, NOTIFY_HOST_ADD, false); #endif #endif } } clk_disable(tegra->clk); tegra_otg_disable_clk(); }
static void otg_notify_state(unsigned long event, int enable) { struct otg_notify *notify = NULL; if (!u_notify) { pr_err("u_notify is NULL\n"); goto no_save_event; } pr_info("%s+ event=%s(%lu), enable=%s\n", __func__, event_string(event), event, enable == 0 ? "off" : "on"); notify = get_otg_notify(); switch (event) { case NOTIFY_EVENT_NONE: break; case NOTIFY_EVENT_SMARTDOCK_USB: case NOTIFY_EVENT_VBUS: if (enable) { u_notify->ndev.mode = NOTIFY_PERIPHERAL_MODE; if (notify->is_wakelock) wake_lock(&u_notify->wlock); if (gpio_is_valid(notify->redriver_en_gpio)) gpio_direction_output (notify->redriver_en_gpio, 1); if (notify->set_peripheral) notify->set_peripheral(true); } else { u_notify->ndev.mode = NOTIFY_NONE_MODE; if (notify->set_peripheral) notify->set_peripheral(false); if (gpio_is_valid(notify->redriver_en_gpio)) gpio_direction_output (notify->redriver_en_gpio, 0); if (notify->is_wakelock) wake_unlock(&u_notify->wlock); } break; case NOTIFY_EVENT_LANHUB_TA: u_notify->diable_v_drive = enable; if (enable) u_notify->oc_noti = 0; if (notify->set_lanhubta) notify->set_lanhubta(enable); break; case NOTIFY_EVENT_LANHUB: if (notify->unsupport_host) { pr_err("This model doesn't support usb host\n"); goto err; } u_notify->diable_v_drive = enable; if (enable) { u_notify->oc_noti = 0; u_notify->ndev.mode = NOTIFY_HOST_MODE; if (notify->is_wakelock) wake_lock(&u_notify->wlock); host_state_notify(&u_notify->ndev, NOTIFY_HOST_ADD); if (gpio_is_valid(notify->redriver_en_gpio)) gpio_direction_output (notify->redriver_en_gpio, 1); if (notify->set_host) notify->set_host(true); } else { u_notify->ndev.mode = NOTIFY_NONE_MODE; if (notify->set_host) notify->set_host(false); if (gpio_is_valid(notify->redriver_en_gpio)) gpio_direction_output (notify->redriver_en_gpio, 0); host_state_notify(&u_notify->ndev, NOTIFY_HOST_REMOVE); if (notify->is_wakelock) wake_unlock(&u_notify->wlock); } break; case NOTIFY_EVENT_HOST: if (notify->unsupport_host) { pr_err("This model doesn't support usb host\n"); goto err; } u_notify->diable_v_drive = 0; if (enable) { u_notify->ndev.mode = NOTIFY_HOST_MODE; if (notify->is_wakelock) wake_lock(&u_notify->wlock); host_state_notify(&u_notify->ndev, NOTIFY_HOST_ADD); if (gpio_is_valid(notify->redriver_en_gpio)) gpio_direction_output (notify->redriver_en_gpio, 1); if (notify->auto_drive_vbus) { u_notify->oc_noti = 1; if (notify->vbus_drive) notify->vbus_drive(1); } if (notify->set_host) notify->set_host(true); } else { u_notify->ndev.mode = NOTIFY_NONE_MODE; if (notify->auto_drive_vbus) { u_notify->oc_noti = 0; if (notify->vbus_drive) notify->vbus_drive(0); } if (notify->set_host) notify->set_host(false); if (gpio_is_valid(notify->redriver_en_gpio)) gpio_direction_output (notify->redriver_en_gpio, 0); host_state_notify(&u_notify->ndev, NOTIFY_HOST_REMOVE); if (notify->is_wakelock) wake_unlock(&u_notify->wlock); } break; case NOTIFY_EVENT_CHARGER: if (notify->set_charger) notify->set_charger(enable); break; case NOTIFY_EVENT_MMDOCK: enable_ovc(u_notify, enable); /* To detect overcurrent, ndev state is initialized */ if (enable) host_state_notify(&u_notify->ndev, NOTIFY_HOST_NONE); case NOTIFY_EVENT_SMARTDOCK_TA: case NOTIFY_EVENT_AUDIODOCK: if (notify->unsupport_host) { pr_err("This model doesn't support usb host\n"); goto err; } u_notify->diable_v_drive = enable; if (enable) { u_notify->ndev.mode = NOTIFY_HOST_MODE; if (notify->is_wakelock) wake_lock(&u_notify->wlock); if (notify->set_host) notify->set_host(true); } else { u_notify->ndev.mode = NOTIFY_NONE_MODE; if (notify->set_host) notify->set_host(false); if (notify->is_wakelock) wake_unlock(&u_notify->wlock); } break; case NOTIFY_EVENT_DRIVE_VBUS: if (notify->unsupport_host) { pr_err("This model doesn't support usb host\n"); goto no_save_event; } if (u_notify->diable_v_drive) { pr_info("cable type=%s disable vbus draw\n", event_string(u_notify->c_type)); goto no_save_event; } u_notify->oc_noti = enable; if (notify->vbus_drive) notify->vbus_drive((bool)enable); goto no_save_event; default: break; } err: if (enable) u_notify->c_type = event; else u_notify->c_type = NOTIFY_EVENT_NONE; no_save_event: pr_info("%s- event=%s, cable=%s\n", __func__, event_string(event), event_string(u_notify->c_type)); }
/* usb cable call back function */ void max77803_muic_usb_cb(u8 usb_mode) { #ifdef CONFIG_USB_HOST_NOTIFY struct host_notifier_platform_data *host_noti_pdata = host_notifier_device.dev.platform_data; int cable_type = max77803_muic_get_charging_type(); #endif if (is_usb_locked) { pr_info("%s: usb locked by mdm\n", __func__); return; } if (usb_mode == USB_CABLE_ATTACHED) { #if defined(CONFIG_MFD_MAX77803) || defined(CONFIG_MFD_MAX77888) g_usbvbus = USB_CABLE_ATTACHED; #endif #ifdef CONFIG_HA_3G if(system_rev >= 6) usb30_redriver_en(1); #elif defined(CONFIG_V1A) || defined(CONFIG_V2A) usb30_redriver_en(1); #endif max77803_set_vbus_state(USB_CABLE_ATTACHED); pr_info("%s - USB_CABLE_ATTACHED\n", __func__); } else if (usb_mode == USB_CABLE_DETACHED) { #if defined(CONFIG_MFD_MAX77803) || defined(CONFIG_MFD_MAX77888) g_usbvbus = USB_CABLE_DETACHED; #endif #ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE #ifdef CONFIG_HA_3G usb30en = 0; #endif #endif #ifdef CONFIG_HA_3G if(system_rev >= 6) usb30_redriver_en(0); #elif defined(CONFIG_V1A) || defined(CONFIG_V2A) usb30_redriver_en(0); #endif max77803_set_vbus_state(USB_CABLE_DETACHED); pr_info("%s - USB_CABLE_DETACHED\n", __func__); } else if (usb_mode == USB_OTGHOST_ATTACHED) { #ifdef CONFIG_USB_HOST_NOTIFY host_noti_pdata->booster(1); host_noti_pdata->ndev.mode = NOTIFY_HOST_MODE; if (host_noti_pdata->usbhostd_start) host_noti_pdata->usbhostd_start(); /* defense code for otg mis-detecing issue */ msleep(50); #endif max77803_check_id_state(0); pr_info("%s - USB_OTGHOST_ATTACHED\n", __func__); } else if (usb_mode == USB_OTGHOST_DETACHED) { max77803_check_id_state(1); #ifdef CONFIG_USB_HOST_NOTIFY host_noti_pdata->ndev.mode = NOTIFY_NONE_MODE; if (host_noti_pdata->usbhostd_stop) host_noti_pdata->usbhostd_stop(); host_noti_pdata->booster(0); #endif pr_info("%s - USB_OTGHOST_DETACHED\n", __func__); } else if (usb_mode == USB_POWERED_HOST_ATTACHED) { #ifdef CONFIG_USB_HOST_NOTIFY host_noti_pdata->powered_booster(1); if (cable_type == CABLE_TYPE_MMDOCK_MUIC) { enable_ovc(1); host_state_notify(&host_noti_pdata->ndev, NOTIFY_HOST_NONE); } if (cable_type == CABLE_TYPE_LANHUB_MUIC) { host_noti_pdata->ndev.mode = NOTIFY_HOST_MODE; if (host_noti_pdata->usbhostd_start) host_noti_pdata->usbhostd_start(); } else start_usbhostd_wakelock(); #endif max77803_check_id_state(0); pr_info("%s - USB_POWERED_HOST_ATTACHED\n", __func__); } else if (usb_mode == USB_POWERED_HOST_DETACHED) { max77803_check_id_state(1); #ifdef CONFIG_USB_HOST_NOTIFY host_noti_pdata->powered_booster(0); if (cable_type == CABLE_TYPE_MMDOCK_MUIC) { enable_ovc(0); } if (host_noti_pdata->ndev.mode == NOTIFY_HOST_MODE) { host_noti_pdata->ndev.mode = NOTIFY_NONE_MODE; if (host_noti_pdata->usbhostd_stop) host_noti_pdata->usbhostd_stop(); } else stop_usbhostd_wakelock(); #endif pr_info("%s - USB_POWERED_HOST_DETACHED\n", __func__); } }
static void extra_notify_state(unsigned long event, int enable) { struct otg_notify *notify = NULL; if (!u_notify) { pr_err("u_notify is NULL\n"); goto err; } pr_info("%s+ event=%s(%lu), enable=%s\n", __func__, event_string(event), event, enable == 0 ? "off" : "on"); notify = get_otg_notify(); switch (event) { case NOTIFY_EVENT_NONE: break; case NOTIFY_EVENT_OVERCURRENT: if (!u_notify->ndev.dev) { pr_err("ndev is NULL. Maybe usb host is not supported.\n"); break; } host_state_notify(&u_notify->ndev, NOTIFY_HOST_OVERCURRENT); pr_err("OTG overcurrent!!!!!!\n"); break; case NOTIFY_EVENT_VBUSPOWER: if (enable) u_notify->ndev.booster = NOTIFY_POWER_ON; else u_notify->ndev.booster = NOTIFY_POWER_OFF; break; case NOTIFY_EVENT_SMSC_OVC: if (enable) ovc_start(u_notify); else ovc_stop(u_notify); break; case NOTIFY_EVENT_SMTD_EXT_CURRENT: if (u_notify->c_type != NOTIFY_EVENT_SMARTDOCK_TA) { pr_err("No smart dock!!!!!!\n"); break; } if (notify->set_battcall) notify->set_battcall (NOTIFY_EVENT_SMTD_EXT_CURRENT, enable); break; case NOTIFY_EVENT_MMD_EXT_CURRENT: if (u_notify->c_type != NOTIFY_EVENT_MMDOCK) { pr_err("No mmdock!!!!!!\n"); break; } if (notify->set_battcall) notify->set_battcall (NOTIFY_EVENT_MMD_EXT_CURRENT, enable); break; default: break; } pr_info("%s- event=%s(%lu), cable=%s\n", __func__, event_string(event), event, event_string(u_notify->c_type)); err: return; }