static void check_and_handle_5v_connection(struct mxs_info *info) { switch (ddi_power_GetPmu5vStatus()) { case new_5v_connection: if (info->is_5v_irq_detected == 0) { /* we must wait for irq_vdd5v handler run first to reset info->sm_new_5v_connection_jiffies. Otherwise the debounce checking is wrong. */; break; } info->is_5v_irq_detected = 0; ddi_power_enable_5v_disconnect_detection(); info->sm_5v_connection_status = _5v_connected_unverified; case existing_5v_connection: if (info->sm_5v_connection_status != _5v_connected_verified) { /* we allow some time to pass before considering * the 5v connection to be ready to use. This * will give the USB system time to enumerate * (coordination with USB driver to be added * in the future). */ /* handle jiffies rollover case */ if ((jiffies - info->sm_new_5v_connection_jiffies) < 0) { info->sm_new_5v_connection_jiffies = jiffies; break; } if ((jiffies_to_msecs(jiffies - info->sm_new_5v_connection_jiffies)) > _5V_DEBOUNCE_TIME_MS) { info->sm_5v_connection_status = _5v_connected_verified; dev_dbg(info->dev, "5v connection verified\n"); if (info->onboard_vbus5v) { if (regulator_is_enabled( info->onboard_vbus5v) > 0) { info->onboard_vbus5v_online = 1; pr_debug("When supply from \ onboard vbus 5v ,\ DO NOT switch to 4p2 \n"); break; } } #ifdef CONFIG_MXS_VBUS_CURRENT_DRAW #ifdef CONFIG_USB_GADGET /* if there is USB 2.0 current limitation requirement, * waiting for USB enum done. */ if ((__raw_readl(REGS_POWER_BASE + HW_POWER_5VCTRL) & BM_POWER_5VCTRL_CHARGE_4P2_ILIMIT) == (0x20 << BP_POWER_5VCTRL_CHARGE_4P2_ILIMIT)) { dev_info(info->dev, "waiting USB enum done...\r\n"); } while ((__raw_readl(REGS_POWER_BASE + HW_POWER_5VCTRL) & BM_POWER_5VCTRL_CHARGE_4P2_ILIMIT) == (0x20 << BP_POWER_5VCTRL_CHARGE_4P2_ILIMIT)) { msleep(50); } #endif #endif ddi_power_Enable4p2(450); /* part of handling for errata. It is * now "somewhat" safe to * turn on vddio interrupts again */ ddi_power_enable_vddio_interrupt(true); } }
static void check_and_handle_5v_connection(struct stmp3xxx_info *info) { switch (ddi_power_GetPmu5vStatus()) { case new_5v_connection: ddi_power_enable_5v_disconnect_detection(); info->sm_5v_connection_status = _5v_connected_unverified; case existing_5v_connection: if (info->sm_5v_connection_status != _5v_connected_verified) { /* we allow some time to pass before considering * the 5v connection to be ready to use. This * will give the USB system time to enumerate * (coordination with USB driver to be added * in the future). */ /* handle jiffies rollover case */ if ((jiffies - info->sm_new_5v_connection_jiffies) < 0) { info->sm_new_5v_connection_jiffies = jiffies; break; } if ((jiffies_to_msecs(jiffies - info->sm_new_5v_connection_jiffies)) > _5V_DEBOUNCE_TIME_MS) { info->sm_5v_connection_status = _5v_connected_verified; dev_info(info->dev, "5v connection verified\n"); ddi_power_Enable4p2(450); /* part of handling for errata. It is * now "somewhat" safe to * turn on vddio interrupts again */ ddi_power_enable_vddio_interrupt(true); } } break; case new_5v_disconnection: ddi_bc_SetDisable(); ddi_bc_SetCurrentLimit(0); if (info->regulator) regulator_set_current_limit(info->regulator, 0, 0); info->is_usb_online = 0; info->is_ac_online = 0; info->sm_5v_connection_status = _5v_disconnected_unverified; case existing_5v_disconnection: if (info->sm_5v_connection_status != _5v_disconnected_verified) { if ((jiffies - info->sm_new_5v_disconnection_jiffies) < 0) { info->sm_new_5v_connection_jiffies = jiffies; break; } if ((jiffies_to_msecs(jiffies - info->sm_new_5v_disconnection_jiffies)) > _5V_DEBOUNCE_TIME_MS) { info->sm_5v_connection_status = _5v_disconnected_verified; ddi_power_execute_5v_to_battery_handoff(); ddi_power_enable_5v_connect_detection(); /* part of handling for errata. * It is now safe to * turn on vddio interrupts again */ ddi_power_enable_vddio_interrupt(true); dev_info(info->dev, "5v disconnection handled\n"); } } break; } }