diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2017-02-09 22:09:28 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-02-09 22:09:28 -0800 |
commit | 3252149cd27aaaf073ae31f1da6eb3eb2fd7d729 (patch) | |
tree | bd3c76dd1b622b430edd68aafeb8d65f4eb863ea /drivers | |
parent | fa12840e3df6183283e410b905c6828c30482bfc (diff) | |
parent | 23d22ee4bf2441c51aae648e078ef7f4ddfa6bc1 (diff) |
Merge "power: smb1351-charger: update drive to support parallel architecture"
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/power/supply/qcom/battery.c | 24 | ||||
-rw-r--r-- | drivers/power/supply/qcom/qpnp-smb2.c | 14 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 159 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smb-lib.h | 3 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smb1351-charger.c | 158 |
5 files changed, 231 insertions, 127 deletions
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 34add97b55d2..86e1bc040266 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -33,6 +33,7 @@ #define TAPER_END_VOTER "TAPER_END_VOTER" #define PL_TAPER_EARLY_BAD_VOTER "PL_TAPER_EARLY_BAD_VOTER" #define PARALLEL_PSY_VOTER "PARALLEL_PSY_VOTER" +#define PL_HW_ABSENT_VOTER "PL_HW_ABSENT_VOTER" struct pl_data { int pl_mode; @@ -44,6 +45,7 @@ struct pl_data { struct votable *pl_disable_votable; struct votable *pl_awake_votable; struct work_struct status_change_work; + struct work_struct pl_disable_forever_work; struct delayed_work pl_taper_work; struct power_supply *main_psy; struct power_supply *pl_psy; @@ -361,6 +363,15 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, return 0; } +static void pl_disable_forever_work(struct work_struct *work) +{ + struct pl_data *chip = container_of(work, + struct pl_data, pl_disable_forever_work); + + /* Disable Parallel charger forever */ + vote(chip->pl_disable_votable, PL_HW_ABSENT_VOTER, true, 0); +} + static int pl_disable_vote_callback(struct votable *votable, void *data, int pl_disable, const char *client) { @@ -372,6 +383,18 @@ static int pl_disable_vote_callback(struct votable *votable, chip->taper_pct = 100; if (!pl_disable) { /* enable */ + rc = power_supply_get_property(chip->pl_psy, + POWER_SUPPLY_PROP_CHARGE_TYPE, &pval); + if (rc == -ENODEV) { + /* + * -ENODEV is returned only if parallel chip + * is not present in the system. + * Disable parallel charger forever. + */ + schedule_work(&chip->pl_disable_forever_work); + return rc; + } + rerun_election(chip->fv_votable); rerun_election(chip->fcc_votable); /* @@ -697,6 +720,7 @@ static int pl_init(void) INIT_WORK(&chip->status_change_work, status_change_work); INIT_DELAYED_WORK(&chip->pl_taper_work, pl_taper_work); + INIT_WORK(&chip->pl_disable_forever_work, pl_disable_forever_work); rc = pl_register_notifier(chip); if (rc < 0) { diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 4e9d2894479a..16b7dd8c2ccd 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -385,6 +385,8 @@ static int smb2_parse_dt(struct smb2 *chip) chg->micro_usb_mode = of_property_read_bool(node, "qcom,micro-usb"); + chg->dcp_icl_ua = chip->dt.usb_icl_ua; + return 0; } @@ -1338,7 +1340,6 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } - chg->dcp_icl_ua = chip->dt.usb_icl_ua; chg->boost_threshold_ua = chip->dt.boost_threshold_ua; rc = smblib_read(chg, APSD_RESULT_STATUS_REG, &stat); @@ -1350,12 +1351,9 @@ static int smb2_init_hw(struct smb2 *chip) smblib_rerun_apsd_if_required(chg); /* clear the ICL override if it is set */ - if (stat & ICL_OVERRIDE_LATCH_BIT) { - rc = smblib_write(chg, CMD_APSD_REG, ICL_OVERRIDE_BIT); - if (rc < 0) { - pr_err("Couldn't disable ICL override rc=%d\n", rc); - return rc; - } + if (smblib_icl_override(chg, false) < 0) { + pr_err("Couldn't disable ICL override rc=%d\n", rc); + return rc; } /* votes must be cast before configuring software control */ @@ -1367,8 +1365,6 @@ static int smb2_init_hw(struct smb2 *chip) DEFAULT_VOTER, true, chip->dt.fcc_ua); vote(chg->fv_votable, DEFAULT_VOTER, true, chip->dt.fv_uv); - vote(chg->usb_icl_votable, - DCP_VOTER, true, chip->dt.usb_icl_ua); vote(chg->dc_icl_votable, DEFAULT_VOTER, true, chip->dt.dc_icl_ua); vote(chg->hvdcp_disable_votable_indirect, DEFAULT_VOTER, diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 16edf875de96..6e01ec6174d5 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -151,6 +151,31 @@ static int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua) return 0; } +int smblib_icl_override(struct smb_charger *chg, bool override) +{ + int rc; + bool override_status; + u8 stat; + + rc = smblib_read(chg, APSD_RESULT_STATUS_REG, &stat); + if (rc < 0) { + smblib_err(chg, "Couldn't read APSD_RESULT_STATUS_REG rc=%d\n", + rc); + return rc; + } + override_status = (bool)(stat & ICL_OVERRIDE_LATCH_BIT); + + if (override != override_status) { + rc = smblib_masked_write(chg, CMD_APSD_REG, + ICL_OVERRIDE_BIT, ICL_OVERRIDE_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't override ICL rc=%d\n", rc); + return rc; + } + } + return 0; +} + /******************** * REGISTER GETTERS * ********************/ @@ -591,6 +616,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) /* reset both usbin current and voltage votes */ vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0); vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); + vote(chg->pl_disable_votable, PL_DISABLE_HVDCP_VOTER, true, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); @@ -728,19 +754,33 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, { struct smb_charger *chg = data; int rc = 0; - bool suspend = (icl_ua < USBIN_25MA); + bool suspend, override; u8 icl_options = 0; + override = true; + /* remove override if no voters or type = SDP or CDP */ + if (client == NULL + || chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB + || chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB_CDP) + override = false; + + suspend = false; + if (client && (icl_ua < USBIN_25MA)) + suspend = true; + if (suspend) goto out; if (chg->usb_psy_desc.type != POWER_SUPPLY_TYPE_USB) { - rc = smblib_set_charge_param(chg, &chg->param.usb_icl, icl_ua); - if (rc < 0) { - smblib_err(chg, "Couldn't set HC ICL rc=%d\n", rc); - return rc; + if (client) { + rc = smblib_set_charge_param(chg, &chg->param.usb_icl, + icl_ua); + if (rc < 0) { + smblib_err(chg, "Couldn't set HC ICL rc=%d\n", + rc); + return rc; + } } - goto out; } @@ -769,10 +809,14 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, } out: + if (override) + icl_options |= USBIN_MODE_CHG_BIT; + rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, - CFG_USB3P0_SEL_BIT | USB51_MODE_BIT, icl_options); + CFG_USB3P0_SEL_BIT | USB51_MODE_BIT | USBIN_MODE_CHG_BIT, + icl_options); if (rc < 0) { - smblib_err(chg, "Couldn't set ICL opetions rc=%d\n", rc); + smblib_err(chg, "Couldn't set ICL options rc=%d\n", rc); return rc; } @@ -783,6 +827,12 @@ out: return rc; } + rc = smblib_icl_override(chg, override); + if (rc < 0) { + smblib_err(chg, "Couldn't set ICL override rc=%d\n", rc); + return rc; + } + return rc; } @@ -1996,11 +2046,11 @@ int smblib_set_prop_usb_current_max(struct smb_charger *chg, true, val->intval); } else if (chg->system_suspend_supported) { if (val->intval <= USBIN_25MA) - rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, - true, val->intval); + rc = vote(chg->usb_icl_votable, + PD_SUSPEND_SUPPORTED_VOTER, true, val->intval); else - rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, - false, 0); + rc = vote(chg->usb_icl_votable, + PD_SUSPEND_SUPPORTED_VOTER, false, 0); } return rc; } @@ -2137,7 +2187,11 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, "Couldn't enable vconn on CC line rc=%d\n", rc); return rc; } - + /* + * Enforce 500mA for PD until the real vote comes in later. + * It is guaranteed that pd_active is set prior to + * pd_current_max + */ rc = vote(chg->usb_icl_votable, PD_VOTER, true, USBIN_500MA); if (rc < 0) { smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", @@ -2145,50 +2199,17 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, return rc; } + /* remove DCP_VOTER */ rc = vote(chg->usb_icl_votable, DCP_VOTER, false, 0); if (rc < 0) { - smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", - rc); - return rc; - } - - rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, - USBIN_MODE_CHG_BIT, USBIN_MODE_CHG_BIT); - if (rc < 0) { - smblib_err(chg, - "Couldn't change USB mode rc=%d\n", rc); - return rc; - } - - rc = smblib_masked_write(chg, CMD_APSD_REG, - ICL_OVERRIDE_BIT, ICL_OVERRIDE_BIT); - if (rc < 0) { - smblib_err(chg, - "Couldn't override APSD rc=%d\n", rc); - return rc; - } - } else { - rc = vote(chg->usb_icl_votable, DCP_VOTER, true, - chg->dcp_icl_ua); - if (rc < 0) { - smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", - rc); + smblib_err(chg, "Couldn't unvote DCP rc=%d\n", rc); return rc; } - rc = smblib_masked_write(chg, CMD_APSD_REG, - ICL_OVERRIDE_BIT, 0); + /* remove USB_PSY_VOTER */ + rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); if (rc < 0) { - smblib_err(chg, - "Couldn't override APSD rc=%d\n", rc); - return rc; - } - - rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, - USBIN_MODE_CHG_BIT, 0); - if (rc < 0) { - smblib_err(chg, - "Couldn't change USB mode rc=%d\n", rc); + smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc); return rc; } } @@ -2782,6 +2803,9 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, if (chg->mode == PARALLEL_MASTER) vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, true, 0); + /* QC authentication done, parallel charger can be enabled now */ + vote(chg->pl_disable_votable, PL_DISABLE_HVDCP_VOTER, false, 0); + /* the APSD done handler will set the USB supply type */ apsd_result = smblib_get_apsd_result(chg); smblib_dbg(chg, PR_INTERRUPT, "IRQ: hvdcp-3p0-auth-done rising; %s detected\n", @@ -2791,6 +2815,8 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, bool rising, bool qc_charger) { + const struct apsd_result *apsd_result = smblib_update_usb_type(chg); + /* Hold off PD only until hvdcp 2.0 detection timeout */ if (rising) { vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, @@ -2798,6 +2824,24 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, if (get_effective_result(chg->pd_disallowed_votable_indirect)) /* could be a legacy cable, try doing hvdcp */ try_rerun_apsd_for_hvdcp(chg); + + /* + * HVDCP detection timeout done + * If adapter is not QC2.0/QC3.0 - it is a plain old DCP. + */ + if (!qc_charger && (apsd_result->bit & DCP_CHARGER_BIT)) + /* enforce DCP ICL if specified */ + vote(chg->usb_icl_votable, DCP_VOTER, + chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua); + /* + * If adapter is not QC2.0/QC3.0 remove vote for parallel + * disable. + * Otherwise if adapter is QC2.0/QC3.0 wait for authentication + * to complete. + */ + if (!qc_charger) + vote(chg->pl_disable_votable, PL_DISABLE_HVDCP_VOTER, + false, 0); } smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n", @@ -2923,12 +2967,19 @@ static void typec_source_removal(struct smb_charger *chg) /* clear USB ICL vote for PD_VOTER */ rc = vote(chg->usb_icl_votable, PD_VOTER, false, 0); if (rc < 0) - smblib_err(chg, "Couldn't un-vote for USB ICL rc=%d\n", rc); + smblib_err(chg, "Couldn't un-vote PD from USB ICL rc=%d\n", rc); /* clear USB ICL vote for USB_PSY_VOTER */ rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); if (rc < 0) - smblib_err(chg, "Couldn't un-vote for USB ICL rc=%d\n", rc); + smblib_err(chg, + "Couldn't un-vote USB_PSY from USB ICL rc=%d\n", rc); + + /* clear USB ICL vote for DCP_VOTER */ + rc = vote(chg->usb_icl_votable, DCP_VOTER, false, 0); + if (rc < 0) + smblib_err(chg, + "Couldn't un-vote DCP from USB ICL rc=%d\n", rc); } static void typec_source_insertion(struct smb_charger *chg) @@ -2957,6 +3008,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, LEGACY_CABLE_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); + vote(chg->pl_disable_votable, PL_DISABLE_HVDCP_VOTER, true, 0); /* reset votes from vbus_cc_short */ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, @@ -3514,6 +3566,7 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0); + vote(chg->pl_disable_votable, PL_DISABLE_HVDCP_VOTER, true, 0); chg->usb_suspend_votable = create_votable("USB_SUSPEND", VOTE_SET_ANY, smblib_usb_suspend_vote_callback, diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index e341484bc2ec..a0190ae44f29 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -52,6 +52,8 @@ enum print_reason { #define HVDCP_INDIRECT_VOTER "HVDCP_INDIRECT_VOTER" #define MICRO_USB_VOTER "MICRO_USB_VOTER" #define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" +#define PD_SUSPEND_SUPPORTED_VOTER "PD_SUSPEND_SUPPORTED_VOTER" +#define PL_DISABLE_HVDCP_VOTER "PL_DISABLE_HVDCP_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 @@ -405,6 +407,7 @@ void smblib_suspend_on_debug_battery(struct smb_charger *chg); int smblib_rerun_apsd_if_required(struct smb_charger *chg); int smblib_get_prop_fcc_delta(struct smb_charger *chg, union power_supply_propval *val); +int smblib_icl_override(struct smb_charger *chg, bool override); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); diff --git a/drivers/power/supply/qcom/smb1351-charger.c b/drivers/power/supply/qcom/smb1351-charger.c index 0c2943c7f2df..d0cf37b0613a 100644 --- a/drivers/power/supply/qcom/smb1351-charger.c +++ b/drivers/power/supply/qcom/smb1351-charger.c @@ -461,7 +461,7 @@ struct smb1351_charger { int parallel_pin_polarity_setting; bool parallel_charger; - bool parallel_charger_present; + bool parallel_charger_suspended; bool bms_controlled_charging; bool apsd_rerun; bool usbin_ov; @@ -873,9 +873,9 @@ static int smb1351_regulator_init(struct smb1351_charger *chip) chip->otg_vreg.rdesc.owner = THIS_MODULE; chip->otg_vreg.rdesc.type = REGULATOR_VOLTAGE; chip->otg_vreg.rdesc.ops = &smb1351_chg_otg_reg_ops; - chip->otg_vreg.rdesc.name = + chip->otg_vreg.rdesc.name = chip->dev->of_node->name; - chip->otg_vreg.rdesc.of_match = + chip->otg_vreg.rdesc.of_match = chip->dev->of_node->name; cfg.dev = chip->dev; @@ -1409,34 +1409,27 @@ static int smb1351_battery_get_property(struct power_supply *psy, static enum power_supply_property smb1351_parallel_properties[] = { POWER_SUPPLY_PROP_CHARGING_ENABLED, POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, + POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_PARALLEL_MODE, }; -static int smb1351_parallel_set_chg_present(struct smb1351_charger *chip, - int present) +static int smb1351_parallel_set_chg_suspend(struct smb1351_charger *chip, + int suspend) { int rc; u8 reg, mask = 0; - if (present == chip->parallel_charger_present) { - pr_debug("present %d -> %d, skipping\n", - chip->parallel_charger_present, present); + if (chip->parallel_charger_suspended == suspend) { + pr_debug("Skip same state request suspended = %d suspend=%d\n", + chip->parallel_charger_suspended, !suspend); return 0; } - if (present) { - /* Check if SMB1351 is present */ - rc = smb1351_read_reg(chip, CHG_REVISION_REG, ®); - if (rc) { - pr_debug("Failed to detect smb1351-parallel-charger, may be absent\n"); - return -ENODEV; - } - + if (!suspend) { rc = smb_chip_get_version(chip); if (rc) { pr_err("Couldn't get version rc = %d\n", rc); @@ -1476,6 +1469,26 @@ static int smb1351_parallel_set_chg_present(struct smb1351_charger *chip, } } + /* control USB suspend via command bits */ + rc = smb1351_masked_write(chip, VARIOUS_FUNC_REG, + APSD_EN_BIT | SUSPEND_MODE_CTRL_BIT, + SUSPEND_MODE_CTRL_BY_I2C); + if (rc) { + pr_err("Couldn't set USB suspend rc=%d\n", rc); + return rc; + } + + /* + * When present is being set force USB suspend, start charging + * only when POWER_SUPPLY_PROP_CURRENT_MAX is set. + */ + rc = smb1351_usb_suspend(chip, CURRENT, true); + if (rc) { + pr_err("failed to suspend rc=%d\n", rc); + return rc; + } + chip->usb_psy_ma = SUSPEND_CURRENT_MA; + /* set chg en by pin active low */ reg = chip->parallel_pin_polarity_setting | USBCS_CTRL_BY_I2C; rc = smb1351_masked_write(chip, CHG_PIN_EN_CTRL_REG, @@ -1485,15 +1498,6 @@ static int smb1351_parallel_set_chg_present(struct smb1351_charger *chip, return rc; } - /* control USB suspend via command bits */ - rc = smb1351_masked_write(chip, VARIOUS_FUNC_REG, - SUSPEND_MODE_CTRL_BIT, - SUSPEND_MODE_CTRL_BY_I2C); - if (rc) { - pr_err("Couldn't set USB suspend rc=%d\n", rc); - return rc; - } - /* * setup USB 2.0/3.0 detection and USB 500/100 * command polarity @@ -1508,23 +1512,21 @@ static int smb1351_parallel_set_chg_present(struct smb1351_charger *chip, return rc; } - /* set fast charging current limit */ - chip->target_fastchg_current_max_ma = SMB1351_CHG_FAST_MIN_MA; rc = smb1351_fastchg_current_set(chip, chip->target_fastchg_current_max_ma); if (rc) { pr_err("Couldn't set fastchg current rc=%d\n", rc); return rc; } - } + chip->parallel_charger_suspended = false; + } else { + rc = smb1351_usb_suspend(chip, CURRENT, true); + if (rc) + pr_debug("failed to suspend rc=%d\n", rc); - chip->parallel_charger_present = present; - /* - * When present is being set force USB suspend, start charging - * only when POWER_SUPPLY_PROP_CURRENT_MAX is set. - */ - chip->usb_psy_ma = SUSPEND_CURRENT_MA; - smb1351_usb_suspend(chip, CURRENT, true); + chip->usb_psy_ma = SUSPEND_CURRENT_MA; + chip->parallel_charger_suspended = true; + } return 0; } @@ -1564,6 +1566,31 @@ static bool smb1351_is_input_current_limited(struct smb1351_charger *chip) return !!(reg & IRQ_IC_LIMIT_STATUS_BIT); } +static bool smb1351_is_usb_present(struct smb1351_charger *chip) +{ + int rc; + union power_supply_propval val = {0, }; + + if (!chip->usb_psy) + chip->usb_psy = power_supply_get_by_name("usb"); + if (!chip->usb_psy) { + pr_err("USB psy not found\n"); + return false; + } + + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_ONLINE, &val); + if (rc < 0) { + pr_err("Failed to get present property rc=%d\n", rc); + return false; + } + + if (val.intval) + return true; + + return false; +} + static int smb1351_parallel_set_property(struct power_supply *psy, enum power_supply_property prop, const union power_supply_propval *val) @@ -1577,38 +1604,30 @@ static int smb1351_parallel_set_property(struct power_supply *psy, *CHG EN is controlled by pin in the parallel charging. *Use suspend if disable charging by command. */ - if (chip->parallel_charger_present) + if (!chip->parallel_charger_suspended) rc = smb1351_usb_suspend(chip, USER, !val->intval); break; - case POWER_SUPPLY_PROP_PRESENT: - rc = smb1351_parallel_set_chg_present(chip, val->intval); + case POWER_SUPPLY_PROP_INPUT_SUSPEND: + rc = smb1351_parallel_set_chg_suspend(chip, val->intval); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - if (chip->parallel_charger_present) { - chip->target_fastchg_current_max_ma = + chip->target_fastchg_current_max_ma = val->intval / 1000; + if (!chip->parallel_charger_suspended) rc = smb1351_fastchg_current_set(chip, chip->target_fastchg_current_max_ma); - } break; case POWER_SUPPLY_PROP_CURRENT_MAX: - if (chip->parallel_charger_present) { - index = smb1351_get_closest_usb_setpoint( - val->intval / 1000); - chip->usb_psy_ma = usb_chg_current[index]; + index = smb1351_get_closest_usb_setpoint(val->intval / 1000); + chip->usb_psy_ma = usb_chg_current[index]; + if (!chip->parallel_charger_suspended) rc = smb1351_set_usb_chg_current(chip, chip->usb_psy_ma); - } break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: - if (chip->parallel_charger_present && - (chip->vfloat_mv != val->intval)) { + chip->vfloat_mv = val->intval / 1000; + if (!chip->parallel_charger_suspended) rc = smb1351_float_voltage_set(chip, val->intval); - if (!rc) - chip->vfloat_mv = val->intval; - } else { - chip->vfloat_mv = val->intval; - } break; default: return -EINVAL; @@ -1638,41 +1657,49 @@ static int smb1351_parallel_get_property(struct power_supply *psy, val->intval = !chip->usb_suspended_status; break; case POWER_SUPPLY_PROP_CURRENT_MAX: - if (chip->parallel_charger_present) + if (!chip->parallel_charger_suspended) val->intval = chip->usb_psy_ma * 1000; else val->intval = 0; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: - val->intval = chip->vfloat_mv; + if (!chip->parallel_charger_suspended) + val->intval = chip->vfloat_mv; + else + val->intval = 0; break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = chip->parallel_charger_present; + case POWER_SUPPLY_PROP_CHARGE_TYPE: + val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; + /* Check if SMB1351 is present */ + if (smb1351_is_usb_present(chip)) { + val->intval = smb1351_get_prop_charge_type(chip); + if (val->intval == POWER_SUPPLY_CHARGE_TYPE_UNKNOWN) { + pr_debug("Failed to charge type, charger may be absent\n"); + return -ENODEV; + } + } break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - if (chip->parallel_charger_present) + if (!chip->parallel_charger_suspended) val->intval = chip->fastchg_current_max_ma * 1000; else val->intval = 0; break; case POWER_SUPPLY_PROP_STATUS: - if (chip->parallel_charger_present) + if (!chip->parallel_charger_suspended) val->intval = smb1351_get_prop_batt_status(chip); else val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: - if (chip->parallel_charger_present) + if (!chip->parallel_charger_suspended) val->intval = smb1351_is_input_current_limited(chip) ? 1 : 0; else val->intval = 0; break; case POWER_SUPPLY_PROP_PARALLEL_MODE: - if (chip->parallel_charger_present) - val->intval = POWER_SUPPLY_PARALLEL_USBIN_USBIN; - else - val->intval = POWER_SUPPLY_PARALLEL_NONE; + val->intval = POWER_SUPPLY_PARALLEL_USBIN_USBIN; break; default: return -EINVAL; @@ -3142,6 +3169,7 @@ static int smb1351_parallel_charger_probe(struct i2c_client *client, chip->client = client; chip->dev = &client->dev; chip->parallel_charger = true; + chip->parallel_charger_suspended = true; chip->usb_suspended_status = of_property_read_bool(node, "qcom,charging-disabled"); |