Loading drivers/power/qpnp-charger.c +68 −12 Original line number Diff line number Diff line Loading @@ -119,7 +119,7 @@ #define USB_SPARE 0xDF #define DC_COMP_OVR1 0xE9 #define CHGR_COMP_OVR1 0xEE #define USB_CHGPTH_CTL 0x40 #define REG_OFFSET_PERP_SUBTYPE 0x05 /* SMBB peripheral subtype values */ Loading Loading @@ -166,6 +166,7 @@ #define OCP_THR_900_MA 0x02 #define OCP_THR_500_MA 0x01 #define OCP_THR_200_MA 0x00 #define DC_HIGHER_PRIORITY BIT(7) /* Interrupt definitions */ /* smbb_chg_interrupts */ Loading Loading @@ -671,6 +672,25 @@ qpnp_chg_is_usb_chg_plugged_in(struct qpnp_chg_chip *chip) return (usb_chgpth_rt_sts & USBIN_VALID_IRQ) ? 1 : 0; } static bool qpnp_is_dc_higher_prio(struct qpnp_chg_chip *chip) { int rc; u8 usb_ctl; if (!chip->type == SMBB) return false; rc = qpnp_chg_read(chip, &usb_ctl, chip->usb_chgpth_base + USB_CHGPTH_CTL, 1); if (rc) { pr_err("failed to read usb ctl rc=%d\n", rc); return 0; } return !!(usb_ctl & DC_HIGHER_PRIORITY); } static bool qpnp_chg_is_ibat_loop_active(struct qpnp_chg_chip *chip) { Loading Loading @@ -1580,7 +1600,10 @@ qpnp_chg_coarse_det_usb_irq_handler(int irq, void *_chip) return IRQ_HANDLED; } #define USB_WALL_THRESHOLD_MA 500 #define ENUM_T_STOP_BIT BIT(0) #define USB_5V_UV 5000000 #define USB_9V_UV 9000000 static irqreturn_t qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip) { Loading Loading @@ -1625,6 +1648,10 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip) qpnp_chg_set_appropriate_vddmax(chip); chip->chg_done = false; } if (!qpnp_is_dc_higher_prio(chip)) qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma); qpnp_chg_usb_suspend_enable(chip, 0); qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); chip->prev_usb_max_ma = -EINVAL; Loading Loading @@ -1802,6 +1829,23 @@ qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip) msecs_to_jiffies(EOC_CHECK_PERIOD_MS)); schedule_work(&chip->soc_check_work); } if (qpnp_is_dc_higher_prio(chip)) { pr_debug("dc has higher priority\n"); if (dc_present) { qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); power_supply_set_voltage_limit(chip->usb_psy, USB_5V_UV); } else { chip->aicl_settled = false; qpnp_chg_iusbmax_set(chip, USB_WALL_THRESHOLD_MA); power_supply_set_voltage_limit(chip->usb_psy, USB_9V_UV); } } pr_debug("psy changed dc_psy\n"); power_supply_changed(&chip->dc_psy); pr_debug("psy changed batt_psy\n"); Loading Loading @@ -2168,8 +2212,7 @@ module_param(charger_monitor, int, 0644); static int ext_ovp_present; module_param(ext_ovp_present, int, 0444); #define USB_WALL_THRESHOLD_MA 500 #define OVP_USB_WALL_THRESHOLD_MA 200 #define OVP_USB_WALL_TRSH_MA 200 static int qpnp_power_get_property_mains(struct power_supply *psy, enum power_supply_property psp, Loading Loading @@ -2543,15 +2586,23 @@ qpnp_batt_external_power_changed(struct power_supply *psy) qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); } else { qpnp_chg_usb_suspend_enable(chip, 0); if (((ret.intval / 1000) > USB_WALL_THRESHOLD_MA) if (qpnp_is_dc_higher_prio(chip) && qpnp_chg_is_dc_chg_plugged_in(chip)) { pr_debug("dc has higher priority\n"); qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); } else if (((ret.intval / 1000) > USB_WALL_THRESHOLD_MA) && (charger_monitor || !chip->charger_monitor_checked)) { if (!qpnp_is_dc_higher_prio(chip)) qpnp_chg_idcmax_set(chip, QPNP_CHG_I_MAX_MIN_100); if (!ext_ovp_present) qpnp_chg_iusbmax_set(chip, USB_WALL_THRESHOLD_MA); else qpnp_chg_iusbmax_set(chip, OVP_USB_WALL_THRESHOLD_MA); OVP_USB_WALL_TRSH_MA); } else { qpnp_chg_iusbmax_set(chip, ret.intval / 1000); } Loading Loading @@ -3996,14 +4047,19 @@ qpnp_batt_power_set_property(struct power_supply *psy, qpnp_batt_system_temp_level_set(chip, val->intval); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX: if (qpnp_chg_is_usb_chg_plugged_in(chip)) if (qpnp_chg_is_usb_chg_plugged_in(chip) && !(qpnp_is_dc_higher_prio(chip) && qpnp_chg_is_dc_chg_plugged_in(chip))) qpnp_chg_iusbmax_set(chip, val->intval / 1000); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM: qpnp_chg_iusb_trim_set(chip, val->intval); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: if (val->intval) qpnp_chg_input_current_settled(chip); else chip->aicl_settled = false; break; case POWER_SUPPLY_PROP_VOLTAGE_MIN: qpnp_chg_vinmin_set(chip, val->intval / 1000); Loading Loading
drivers/power/qpnp-charger.c +68 −12 Original line number Diff line number Diff line Loading @@ -119,7 +119,7 @@ #define USB_SPARE 0xDF #define DC_COMP_OVR1 0xE9 #define CHGR_COMP_OVR1 0xEE #define USB_CHGPTH_CTL 0x40 #define REG_OFFSET_PERP_SUBTYPE 0x05 /* SMBB peripheral subtype values */ Loading Loading @@ -166,6 +166,7 @@ #define OCP_THR_900_MA 0x02 #define OCP_THR_500_MA 0x01 #define OCP_THR_200_MA 0x00 #define DC_HIGHER_PRIORITY BIT(7) /* Interrupt definitions */ /* smbb_chg_interrupts */ Loading Loading @@ -671,6 +672,25 @@ qpnp_chg_is_usb_chg_plugged_in(struct qpnp_chg_chip *chip) return (usb_chgpth_rt_sts & USBIN_VALID_IRQ) ? 1 : 0; } static bool qpnp_is_dc_higher_prio(struct qpnp_chg_chip *chip) { int rc; u8 usb_ctl; if (!chip->type == SMBB) return false; rc = qpnp_chg_read(chip, &usb_ctl, chip->usb_chgpth_base + USB_CHGPTH_CTL, 1); if (rc) { pr_err("failed to read usb ctl rc=%d\n", rc); return 0; } return !!(usb_ctl & DC_HIGHER_PRIORITY); } static bool qpnp_chg_is_ibat_loop_active(struct qpnp_chg_chip *chip) { Loading Loading @@ -1580,7 +1600,10 @@ qpnp_chg_coarse_det_usb_irq_handler(int irq, void *_chip) return IRQ_HANDLED; } #define USB_WALL_THRESHOLD_MA 500 #define ENUM_T_STOP_BIT BIT(0) #define USB_5V_UV 5000000 #define USB_9V_UV 9000000 static irqreturn_t qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip) { Loading Loading @@ -1625,6 +1648,10 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip) qpnp_chg_set_appropriate_vddmax(chip); chip->chg_done = false; } if (!qpnp_is_dc_higher_prio(chip)) qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma); qpnp_chg_usb_suspend_enable(chip, 0); qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); chip->prev_usb_max_ma = -EINVAL; Loading Loading @@ -1802,6 +1829,23 @@ qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip) msecs_to_jiffies(EOC_CHECK_PERIOD_MS)); schedule_work(&chip->soc_check_work); } if (qpnp_is_dc_higher_prio(chip)) { pr_debug("dc has higher priority\n"); if (dc_present) { qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); power_supply_set_voltage_limit(chip->usb_psy, USB_5V_UV); } else { chip->aicl_settled = false; qpnp_chg_iusbmax_set(chip, USB_WALL_THRESHOLD_MA); power_supply_set_voltage_limit(chip->usb_psy, USB_9V_UV); } } pr_debug("psy changed dc_psy\n"); power_supply_changed(&chip->dc_psy); pr_debug("psy changed batt_psy\n"); Loading Loading @@ -2168,8 +2212,7 @@ module_param(charger_monitor, int, 0644); static int ext_ovp_present; module_param(ext_ovp_present, int, 0444); #define USB_WALL_THRESHOLD_MA 500 #define OVP_USB_WALL_THRESHOLD_MA 200 #define OVP_USB_WALL_TRSH_MA 200 static int qpnp_power_get_property_mains(struct power_supply *psy, enum power_supply_property psp, Loading Loading @@ -2543,15 +2586,23 @@ qpnp_batt_external_power_changed(struct power_supply *psy) qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); } else { qpnp_chg_usb_suspend_enable(chip, 0); if (((ret.intval / 1000) > USB_WALL_THRESHOLD_MA) if (qpnp_is_dc_higher_prio(chip) && qpnp_chg_is_dc_chg_plugged_in(chip)) { pr_debug("dc has higher priority\n"); qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100); } else if (((ret.intval / 1000) > USB_WALL_THRESHOLD_MA) && (charger_monitor || !chip->charger_monitor_checked)) { if (!qpnp_is_dc_higher_prio(chip)) qpnp_chg_idcmax_set(chip, QPNP_CHG_I_MAX_MIN_100); if (!ext_ovp_present) qpnp_chg_iusbmax_set(chip, USB_WALL_THRESHOLD_MA); else qpnp_chg_iusbmax_set(chip, OVP_USB_WALL_THRESHOLD_MA); OVP_USB_WALL_TRSH_MA); } else { qpnp_chg_iusbmax_set(chip, ret.intval / 1000); } Loading Loading @@ -3996,14 +4047,19 @@ qpnp_batt_power_set_property(struct power_supply *psy, qpnp_batt_system_temp_level_set(chip, val->intval); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX: if (qpnp_chg_is_usb_chg_plugged_in(chip)) if (qpnp_chg_is_usb_chg_plugged_in(chip) && !(qpnp_is_dc_higher_prio(chip) && qpnp_chg_is_dc_chg_plugged_in(chip))) qpnp_chg_iusbmax_set(chip, val->intval / 1000); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM: qpnp_chg_iusb_trim_set(chip, val->intval); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: if (val->intval) qpnp_chg_input_current_settled(chip); else chip->aicl_settled = false; break; case POWER_SUPPLY_PROP_VOLTAGE_MIN: qpnp_chg_vinmin_set(chip, val->intval / 1000); Loading