static int chg_uv(struct smb349_charger *chip, u8 status) { /* use this to detect USB insertion only if !apsd */ if (chip->disable_apsd && status == 0) { chip->chg_present = true; dev_dbg(chip->dev, "%s updating usb_psy present=%d", __func__, chip->chg_present); power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_USB); power_supply_set_present(chip->usb_psy, chip->chg_present); } if (status != 0) { chip->chg_present = false; dev_dbg(chip->dev, "%s updating usb_psy present=%d", __func__, chip->chg_present); power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_UNKNOWN); power_supply_set_present(chip->usb_psy, chip->chg_present); } dev_dbg(chip->dev, "chip->chg_present = %d\n", chip->chg_present); return 0; }
static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) { static int power_supply_type; struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg); if (!dotg->psy || !dotg->charger) { dev_err(phy->dev, "no usb power supply/charger registered\n"); return 0; } if (dotg->charger->charging_disabled) return 0; if (dotg->charger->chg_type == DWC3_SDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || #ifdef CONFIG_ZTEMT_COMM_CHARGE dotg->charger->chg_type == DWC3_FLOATED_CHARGER || #endif dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; else power_supply_type = POWER_SUPPLY_TYPE_BATTERY; power_supply_set_supply_type(dotg->psy, power_supply_type); if (dotg->charger->chg_type == DWC3_CDP_CHARGER) mA = DWC3_IDEV_CHG_MAX; if (dotg->charger->max_power == mA) return 0; dev_info(phy->dev, "Avail curr from USB = %u\n", mA); if (dotg->charger->max_power <= 2 && mA > 2) { /* Enable charging */ if (power_supply_set_online(dotg->psy, true)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { /* Disable charging */ if (power_supply_set_online(dotg->psy, false)) goto psy_error; /* Set max current limit */ if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; } power_supply_changed(dotg->psy); dotg->charger->max_power = mA; return 0; psy_error: dev_dbg(phy->dev, "power supply error when setting property\n"); return -ENXIO; }
static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) { static int power_supply_type; struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg); #if defined(CONFIG_DWC3_MSM_BC_12_VZW_SUPPORT) && defined(CONFIG_LGE_PM) static bool chglogo_check = false; #endif if (!dotg->psy || !dotg->charger) { dev_err(phy->dev, "no usb power supply/charger registered\n"); return 0; } if (dotg->charger->charging_disabled) return 0; #ifdef CONFIG_LGE_PM if (dotg->charger->chg_type == DWC3_SDP_CHARGER || dotg->charger->chg_type == DWC3_FLOATED_CHARGER) #else if (dotg->charger->chg_type == DWC3_SDP_CHARGER) #endif power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; else power_supply_type = POWER_SUPPLY_TYPE_UNKNOWN; #ifndef CONFIG_LGE_PM power_supply_set_supply_type(dotg->psy, power_supply_type); #endif #if defined (CONFIG_TOUCHSCREEN_SYNAPTICS_G3) && defined (CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) update_status(1, dotg->charger->chg_type); #endif #if defined(CONFIG_DWC3_MSM_BC_12_VZW_SUPPORT) && defined(CONFIG_LGE_PM) if (!chglogo_check && lge_get_boot_mode() == LGE_BOOT_MODE_CHARGERLOGO && dotg->charger->chg_type == DWC3_SDP_CHARGER) { if (mA > IUNIT) chglogo_check = true; else if (mA <= 2) { dotg->charger->max_power = mA; return 0; } } if (mA > 2 && lge_pm_get_cable_type() != NO_INIT_CABLE) { if (dotg->charger->chg_type == DWC3_DCP_CHARGER) mA = lge_pm_get_ta_current(); } #elif defined(CONFIG_LGE_PM) if (mA > 2 && lge_pm_get_cable_type() != NO_INIT_CABLE) { if (dotg->charger->chg_type == DWC3_SDP_CHARGER) { if (dotg->dwc->gadget.speed == USB_SPEED_SUPER) { if (dotg->charger->max_power > 2) dotg->charger->max_power = 0; mA = DWC3_USB30_CHG_CURRENT; } else { mA = lge_pm_get_usb_current(); } #ifdef CONFIG_QPNP_CHARGER /* For MST, boost current up over 900mA in spite of USB */ if (pseudo_batt_info.mode && mA == 500 ) mA = DWC3_USB30_CHG_CURRENT; #endif } else if (dotg->charger->chg_type == DWC3_DCP_CHARGER) { mA = lge_pm_get_ta_current(); } else if (dotg->charger->chg_type == DWC3_FLOATED_CHARGER) { mA = lge_pm_get_usb_current(); } } #endif if (dotg->charger->chg_type == DWC3_CDP_CHARGER) mA = DWC3_IDEV_CHG_MAX; if (dotg->charger->max_power == mA) return 0; dev_info(phy->dev, "Avail curr from USB = %u\n", mA); /* */ #ifdef CONFIG_LGE_PM #ifndef CONFIG_USB_DWC3_LGE_SINGLE_PSY if (dwc3_otg_get_psy(phy) < 0) goto psy_error; #else if (strcmp(dotg->psy->name, "usb")) { pr_info("%s psy name is %s, so change psy to usb.\n", __func__, dotg->psy->name); dotg->psy = power_supply_get_by_name("usb"); if (!dotg->psy) goto psy_error; } #endif power_supply_set_supply_type(dotg->psy, power_supply_type); #endif #if defined(CONFIG_DWC3_MSM_BC_12_VZW_SUPPORT) && defined(CONFIG_LGE_PM) if (dotg->charger->max_power <= IUNIT && mA > 2) { #else if (dotg->charger->max_power <= 2 && mA > 2) { #endif /* Enable charging */ if (power_supply_set_online(dotg->psy, true)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; #ifdef CONFIG_QPNP_CHARGER if (!strncmp(dotg->psy->name, "ac", 2)) { dotg->psy = power_supply_get_by_name("usb"); if (!dotg->psy) goto psy_error; if (power_supply_set_online(dotg->psy, true)) goto psy_error; if (power_supply_set_supply_type(dotg->psy, power_supply_type)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; dotg->psy = power_supply_get_by_name("ac"); if (!dotg->psy) goto psy_error; } #endif } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { /* Disable charging */ if (power_supply_set_online(dotg->psy, false)) goto psy_error; /* Set max current limit */ if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; #ifdef CONFIG_QPNP_CHARGER if (!strncmp(dotg->psy->name, "ac", 2)) { dotg->psy = power_supply_get_by_name("usb"); if (!dotg->psy) goto psy_error; if (power_supply_set_online(dotg->psy, false)) goto psy_error; if (power_supply_set_supply_type(dotg->psy, power_supply_type)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; dotg->psy = power_supply_get_by_name("ac"); if (!dotg->psy) goto psy_error; } #endif #ifndef CONFIG_USB_DWC3_LGE_SINGLE_PSY dotg->charger->chg_type = DWC3_INVALID_CHARGER; #endif } power_supply_changed(dotg->psy); dotg->charger->max_power = mA; #if defined (CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) #if defined (CONFIG_TOUCHSCREEN_SYNAPTICS_G2) || defined (CONFIG_MACH_MSM8974_TIGERS) queue_work(touch_otg_wq, &dotg->touch_work); #endif #endif return 0; psy_error: dev_dbg(phy->dev, "power supply error when setting property\n"); return -ENXIO; } /* IRQs which OTG driver is interested in handling */ #define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \ DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) /** * dwc3_otg_interrupt - interrupt handler for dwc3 otg events. * @_dotg: Pointer to out controller context structure * * Returns IRQ_HANDLED on success otherwise IRQ_NONE. */ static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg) { struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg; u32 osts, oevt_reg; int ret = IRQ_NONE; int handled_irqs = 0; struct usb_phy *phy = dotg->otg.phy; oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT); if (!(oevt_reg & DWC3_OEVT_MASK)) return IRQ_NONE; osts = dwc3_readl(dotg->regs, DWC3_OSTS); if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) || (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) { /* * ID sts has changed, set inputs later, in the workqueue * function, switch from A to B or from B to A. */ if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) { if (osts & DWC3_OTG_OSTS_CONIDSTS) { dev_dbg(phy->dev, "ID set\n"); set_bit(ID, &dotg->inputs); } else { dev_dbg(phy->dev, "ID clear\n"); clear_bit(ID, &dotg->inputs); } handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT; } if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) { if (osts & DWC3_OTG_OSTS_BSESVALID) { dev_dbg(phy->dev, "BSV set\n"); set_bit(B_SESS_VLD, &dotg->inputs); } else { dev_dbg(phy->dev, "BSV clear\n"); clear_bit(B_SESS_VLD, &dotg->inputs); } handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT; } queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0); ret = IRQ_HANDLED; /* Clear the interrupts we handled */ dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs); } return ret; } /** * dwc3_otg_init_sm - initialize OTG statemachine input * @dotg: Pointer to the dwc3_otg structure * */ void dwc3_otg_init_sm(struct dwc3_otg *dotg) { u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS); struct usb_phy *phy = dotg->otg.phy; struct dwc3_ext_xceiv *ext_xceiv; int ret; dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts); /* * VBUS initial state is reported after PMIC * driver initialization. Wait for it. */ ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5); if (!ret) { dev_err(phy->dev, "%s: completion timeout\n", __func__); /* We can safely assume no cable connected */ set_bit(ID, &dotg->inputs); } ext_xceiv = dotg->ext_xceiv; dwc3_otg_reset(dotg); if (ext_xceiv && !ext_xceiv->otg_capability) { if (osts & DWC3_OTG_OSTS_CONIDSTS) set_bit(ID, &dotg->inputs); else clear_bit(ID, &dotg->inputs); if (osts & DWC3_OTG_OSTS_BSESVALID) set_bit(B_SESS_VLD, &dotg->inputs); else clear_bit(B_SESS_VLD, &dotg->inputs); } }
int smb358_chg_uv(struct opchg_charger *chip, u8 status) { int rc = 0; if(chip->chg_present && (status == 0)){ pr_err("%s chg has plugged in,return\n",__func__); return 0; } opchg_inout_charge_parameters(chip); //opchg_switch_to_usbin(chip,!status); if (status == 0) { chip->g_chg_in = 1; if(chip->g_is_wakeup == 0){ //if awake not be lock,lock it here else do nothing __pm_stay_awake(&chip->source); chip->g_is_wakeup= 1; } } else { chip->g_chg_in = 0; schedule_delayed_work(&chip->opchg_delayed_wakeup_work, round_jiffies_relative(msecs_to_jiffies(2000))); } /* use this to detect USB insertion only if !apsd */ if (chip->disable_apsd && status == 0) { chip->chg_present = true; dev_dbg(chip->dev, "%s updating usb_psy present=%d", __func__, chip->chg_present); power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_USB); power_supply_set_present(chip->usb_psy, chip->chg_present); } if (status != 0) { chip->chg_present = false; dev_dbg(chip->dev, "%s updating usb_psy present=%d", __func__, chip->chg_present); /* we can't set usb_psy as UNKNOWN so early, it'll lead USERSPACE issue */ power_supply_set_present(chip->usb_psy, chip->chg_present); if (chip->bms_controlled_charging){ /* * Disable SOC based USB suspend to enable charging on * USB insertion. */ rc = smb358_charging_disable(chip, SOC, false); if (rc < 0) dev_err(chip->dev,"Couldn't disable usb suspend rc = %d\n",rc); } } //chip->BMT_status.charger_exist = chip->chg_present; power_supply_changed(chip->usb_psy); if(is_project(OPPO_15005)){ schedule_work(&chip->opchg_modify_tp_param_work); } dev_dbg(chip->dev, "chip->chg_present = %d\n", chip->chg_present); return 0; }
static int apsd_complete(struct smb349_charger *chip, u8 status) { int rc; u8 reg = 0; enum power_supply_type type = POWER_SUPPLY_TYPE_UNKNOWN; /* * If apsd is disabled, charger detection is done by * DCIN UV irq. * status = ZERO - indicates charger removed, handled * by DCIN UV irq */ if (chip->disable_apsd || status == 0) { dev_dbg(chip->dev, "APSD %s, status = %d\n", chip->disable_apsd ? "disabled" : "enabled", !!status); return 0; } rc = smb349_read_reg(chip, STATUS_D_REG, ®); if (rc) { dev_err(chip->dev, "Couldn't read STATUS D rc = %d\n", rc); return rc; } dev_dbg(chip->dev, "%s: STATUS_D_REG=%x\n", __func__, reg); switch (reg) { case STATUS_D_PORT_ACA_DOCK: case STATUS_D_PORT_ACA_C: case STATUS_D_PORT_ACA_B: case STATUS_D_PORT_ACA_A: type = POWER_SUPPLY_TYPE_USB_ACA; break; case STATUS_D_PORT_CDP: type = POWER_SUPPLY_TYPE_USB_CDP; break; case STATUS_D_PORT_DCP: type = POWER_SUPPLY_TYPE_USB_DCP; break; case STATUS_D_PORT_SDP: type = POWER_SUPPLY_TYPE_USB; break; case STATUS_D_PORT_OTHER: type = POWER_SUPPLY_TYPE_USB_DCP; break; default: type = POWER_SUPPLY_TYPE_USB; break; } chip->chg_present = !!status; /* * Report the charger type as UNKNOWN if the * apsd-fail flag is set. This nofifies the USB driver * to initiate a s/w based charger type detection. */ if (chip->workaround_flags & WRKARND_APSD_FAIL) type = POWER_SUPPLY_TYPE_UNKNOWN; dev_dbg(chip->dev, "APSD complete. USB type detected=%d chg_present=%d", type, chip->chg_present); power_supply_set_supply_type(chip->usb_psy, type); /* SMB is now done sampling the D+/D- lines, indicate USB driver */ dev_dbg(chip->dev, "%s updating usb_psy present=%d", __func__, chip->chg_present); power_supply_set_present(chip->usb_psy, chip->chg_present); return 0; }
static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) { static int power_supply_type; struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg); if (!dotg->psy || !dotg->charger) { dev_err(phy->dev, "no usb power supply/charger registered\n"); return 0; } if (dotg->charger->charging_disabled) return 0; if (dotg->charger->chg_type == DWC3_SDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; else power_supply_type = POWER_SUPPLY_TYPE_BATTERY; power_supply_set_supply_type(dotg->psy, power_supply_type); if (dotg->charger->chg_type == DWC3_CDP_CHARGER) mA = DWC3_IDEV_CHG_MAX; if (dotg->charger->max_power == mA) return 0; dev_info(phy->dev, "Avail curr from USB = %u\n", mA); if (dotg->charger->max_power <= 2 && mA > 2) { /* Enable charging */ if (power_supply_set_online(dotg->psy, true)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { #if defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349) || defined(CONFIG_PANTECH_PMIC_CHARGER_BQ2419X) if(!dotg->dwc->vbus_active) { dev_dbg(phy->dev, "%s : charger cable disconnection\n", __func__); /* Disable charging */ if (power_supply_set_online(dotg->psy, false)) goto psy_error; /* Set max current limit */ if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; } #else /* Disable charging */ if (power_supply_set_online(dotg->psy, false)) goto psy_error; /* Set max current limit */ if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; #endif /* defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349) */ } power_supply_changed(dotg->psy); dotg->charger->max_power = mA; return 0; psy_error: dev_dbg(phy->dev, "power supply error when setting property\n"); return -ENXIO; }
static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) { static int power_supply_type; struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg); if (!dotg->psy || !dotg->charger) { dev_err(phy->dev, "no usb power supply/charger registered\n"); return 0; } if (dotg->charger->charging_disabled) return 0; if (dotg->charger->chg_type == DWC3_SDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) { #ifdef CONFIG_MACH_MSM8974_14001 /* [email protected], 2015/03/20, Modify for some usb3.0 port detected as USB_CDP ,can not show charge icon when charge */ power_supply_type = POWER_SUPPLY_TYPE_USB; #else power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; #endif /*CONFIG_MACH_MSM8974_14001*/ } else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER || dotg->charger->chg_type == DWC3_FLOATED_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; else power_supply_type = POWER_SUPPLY_TYPE_BATTERY; power_supply_set_supply_type(dotg->psy, power_supply_type); if (dotg->charger->chg_type == DWC3_CDP_CHARGER) mA = DWC3_IDEV_CHG_MAX; /* OPPO 2013-11-05 wangjc Add begin for enable non standard charging */ #ifdef CONFIG_MACH_MSM8974_14001 if (dotg->charger->chg_type == DWC3_FLOATED_CHARGER) mA = DWC3_IDEV_CHG_FLOATED; #endif /* OPPO 2013-11-05 wangjc Add end */ if (dotg->charger->max_power == mA) return 0; dev_info(phy->dev, "Avail curr from USB = %u\n", mA); if (dotg->charger->max_power <= 2 && mA > 2) { /* Enable charging */ if (power_supply_set_online(dotg->psy, true)) goto psy_error; #ifdef CONFIG_MACH_MSM8974_14001 /* [email protected], 2014/06/06 Add for slove it show usb icon when plug in charger */ if(power_supply_type != POWER_SUPPLY_TYPE_USB) { power_supply_set_online(dotg->psy, false); } #endif /*CONFIG_MACH_MSM8974_14001*/ if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { /* Disable charging */ /* OPPO 2013-11-20 wangjc Add begin for don't set online to false when usb is still plug in */ #ifdef CONFIG_MACH_MSM8974_14001 if(power_supply_type != POWER_SUPPLY_TYPE_USB) { if (power_supply_set_online(dotg->psy, false)) goto psy_error; /* Set max current limit */ if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; } #endif /* OPPO 2013-11-20 wangjc Add end */ } power_supply_changed(dotg->psy); /* OPPO 2013-12-01 wangjc Add begin for non standard charger detect, HW_VERSION__12 is dvt */ #ifdef CONFIG_MACH_MSM8974_14001 #if defined(CONFIG_OPPO_DEVICE_FIND7) || defined(CONFIG_OPPO_DEVICE_FIND7WX) if(get_pcb_version() < HW_VERSION__12) { if(mA == 500) { non_standard = false; } } #endif #endif /* OPPO 2013-12-01 wangjc Add end */ dotg->charger->max_power = mA; return 0; psy_error: dev_dbg(phy->dev, "power supply error when setting property\n"); return -ENXIO; }
static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) { enum power_supply_property power_supply_type; struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg); if (!dotg->psy || !dotg->charger) { dev_err(phy->dev, "no usb power supply/charger registered\n"); return 0; } if (dotg->charger->charging_disabled) return 0; if (dotg->charger->chg_type != DWC3_INVALID_CHARGER) { dev_dbg(phy->dev, "SKIP setting power supply type again,chg_type = %d\n", dotg->charger->chg_type); goto skip_psy_type; } if (dotg->charger->chg_type == DWC3_SDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; else power_supply_type = POWER_SUPPLY_TYPE_UNKNOWN; power_supply_set_supply_type(dotg->psy, power_supply_type); skip_psy_type: if (dotg->charger->chg_type == DWC3_CDP_CHARGER) mA = DWC3_IDEV_CHG_MAX; if (dotg->charger->max_power == mA) return 0; dev_info(phy->dev, "Avail curr from USB = %u\n", mA); if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { /* Disable charging */ if (power_supply_set_online(dotg->psy, false)) goto psy_error; } else { /* Enable charging */ if (power_supply_set_online(dotg->psy, true)) goto psy_error; } /* Set max current limit in uA */ if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; power_supply_changed(dotg->psy); dotg->charger->max_power = mA; return 0; psy_error: dev_dbg(phy->dev, "power supply error when setting property\n"); return -ENXIO; }
static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) { static int power_supply_type; struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg); struct power_supply *saved_usb_psy = NULL; struct power_supply *ac_psy = NULL; if (!dotg->psy || !dotg->charger) { dev_err(phy->dev, "no usb power supply/charger registered\n"); return 0; } if (dotg->charger->charging_disabled) return 0; if (dotg->charger->chg_type == DWC3_SDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; else power_supply_type = POWER_SUPPLY_TYPE_BATTERY; power_supply_set_supply_type(dotg->psy, power_supply_type); if ((dotg->charger->chg_type == DWC3_CDP_CHARGER) && mA > 0) mA = DWC3_IDEV_CHG_MAX; if (slimport_is_connected() && mA) { mA = slimport_get_chg_current(); if (mA > DWC3_IDEV_CHG_MIN) dotg->charger->chg_type = DWC3_DCP_CHARGER; } if (dotg->charger->max_power == mA) return 0; dev_info(phy->dev, "Avail curr from USB = %u\n", mA); ac_psy = power_supply_get_by_name("ac"); if (dotg->charger->chg_type == DWC3_DCP_CHARGER && ac_psy) { pr_info("%s: override dotg->psy to ac->psy\n", __func__); saved_usb_psy = dotg->psy; dotg->psy = ac_psy; } pr_info("dotg->charger->max_power = %d "\ "ma = %d\n", dotg->charger->max_power, mA); if (dotg->charger->max_power <= 2 && mA > 2) { /* Enable charging */ if (power_supply_set_online(dotg->psy, true)) goto psy_error; if (!strcmp(dotg->psy->name, "usb")) { if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; } } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { /* Disable charging */ if (power_supply_set_online(dotg->psy, false)) goto psy_error; if (!strcmp(dotg->psy->name, "usb")) { if (power_supply_set_online(ac_psy, false)) goto psy_error; /* Set max current limit */ if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; } } if (saved_usb_psy) dotg->psy = saved_usb_psy; power_supply_changed(dotg->psy); dotg->charger->max_power = mA; return 0; psy_error: dev_dbg(phy->dev, "power supply error when setting property\n"); return -ENXIO; }
static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) { static int power_supply_type; struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg); #if defined(CONFIG_DWC3_MSM_BC_12_VZW_SUPPORT) && defined(CONFIG_LGE_PM) static bool chglogo_check = false; #endif if (!dotg->psy || !dotg->charger) { dev_err(phy->dev, "no usb power supply/charger registered\n"); return 0; } if (dotg->charger->charging_disabled) return 0; #ifdef CONFIG_LGE_PM if (dotg->charger->chg_type == DWC3_SDP_CHARGER || dotg->charger->chg_type == DWC3_FLOATED_CHARGER) #else if (dotg->charger->chg_type == DWC3_SDP_CHARGER) #endif power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; else #ifdef CONFIG_LGE_PM /* [email protected] * healthd get battery psy type at init only. * If cable detach before healthd init, * healthd recognize usb psy as battery type. */ power_supply_type = POWER_SUPPLY_TYPE_UNKNOWN; #else power_supply_type = POWER_SUPPLY_TYPE_BATTERY; #endif #ifndef CONFIG_LGE_PM power_supply_set_supply_type(dotg->psy, power_supply_type); #endif #if defined (CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) update_status(1, dotg->charger->chg_type); #endif #if defined(CONFIG_DWC3_MSM_BC_12_VZW_SUPPORT) && defined(CONFIG_LGE_PM) if (!chglogo_check && lge_get_boot_mode() == LGE_BOOT_MODE_CHARGERLOGO && dotg->charger->chg_type == DWC3_SDP_CHARGER) { if (mA > IUNIT) chglogo_check = true; else if (mA <= 2) { dotg->charger->max_power = mA; return 0; } } if (mA > 2 && lge_pm_get_cable_type() != NO_INIT_CABLE) { if (dotg->charger->chg_type == DWC3_DCP_CHARGER) mA = lge_pm_get_ta_current(); } #elif defined(CONFIG_LGE_PM) if (mA > 2 && lge_pm_get_cable_type() != NO_INIT_CABLE) { if (dotg->charger->chg_type == DWC3_SDP_CHARGER) { if (dotg->dwc->gadget.speed == USB_SPEED_SUPER) { if (dotg->charger->max_power > 2) dotg->charger->max_power = 0; mA = DWC3_USB30_CHG_CURRENT; } else { mA = lge_pm_get_usb_current(); } #ifdef CONFIG_QPNP_CHARGER /* For MST, boost current up over 900mA in spite of USB */ if (pseudo_batt_info.mode && mA == 500 ) mA = DWC3_USB30_CHG_CURRENT; #endif } else if (dotg->charger->chg_type == DWC3_DCP_CHARGER) { mA = lge_pm_get_ta_current(); } else if (dotg->charger->chg_type == DWC3_FLOATED_CHARGER) { mA = lge_pm_get_usb_current(); } } #endif if (dotg->charger->chg_type == DWC3_CDP_CHARGER) mA = DWC3_IDEV_CHG_MAX; if (dotg->charger->max_power == mA) return 0; dev_info(phy->dev, "Avail curr from USB = %u\n", mA); /* [email protected] make psy getter and move it above power_supply_type setter. 2014-02-06 */ #ifdef CONFIG_LGE_PM #ifndef CONFIG_USB_DWC3_LGE_SINGLE_PSY if (dwc3_otg_get_psy(phy) < 0) goto psy_error; #else if (strcmp(dotg->psy->name, "usb")) { pr_info("%s psy name is %s, so change psy to usb.\n", __func__, dotg->psy->name); dotg->psy = power_supply_get_by_name("usb"); if (!dotg->psy) goto psy_error; } #endif power_supply_set_supply_type(dotg->psy, power_supply_type); #endif if (dotg->charger->max_power <= 2 && mA > 2) { /* Enable charging */ if (power_supply_set_online(dotg->psy, true)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; #ifdef CONFIG_QPNP_CHARGER if (!strncmp(dotg->psy->name, "ac", 2)) { dotg->psy = power_supply_get_by_name("usb"); if (!dotg->psy) goto psy_error; if (power_supply_set_online(dotg->psy, true)) goto psy_error; if (power_supply_set_supply_type(dotg->psy, power_supply_type)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 1000*mA)) goto psy_error; dotg->psy = power_supply_get_by_name("ac"); if (!dotg->psy) goto psy_error; } #endif } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { /* Disable charging */ if (power_supply_set_online(dotg->psy, false)) goto psy_error; /* Set max current limit */ if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; #ifdef CONFIG_QPNP_CHARGER if (!strncmp(dotg->psy->name, "ac", 2)) { dotg->psy = power_supply_get_by_name("usb"); if (!dotg->psy) goto psy_error; if (power_supply_set_online(dotg->psy, false)) goto psy_error; if (power_supply_set_supply_type(dotg->psy, power_supply_type)) goto psy_error; if (power_supply_set_current_limit(dotg->psy, 0)) goto psy_error; dotg->psy = power_supply_get_by_name("ac"); if (!dotg->psy) goto psy_error; } #endif } power_supply_changed(dotg->psy); dotg->charger->max_power = mA; return 0; psy_error: dev_dbg(phy->dev, "power supply error when setting property\n"); return -ENXIO; }