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