From 683a347835e6aa2a70af3f3af4e552d92b1243f9 Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Wed, 8 Feb 2017 10:47:37 -0800 Subject: [PATCH 1/3] power: supply: qcom: implement die and connector health property The die and connector health properties expose the comparator output of the thermal regulation. If both die and skin temperature regulation is enabled then the output of the comparator will be the higher of the two. The property values can be one of: Unknown, Cool, Warm, Hot, Overheat. Change-Id: Ic92c9cb08ec42fd2c2f26a54687a17e3b05b388f Signed-off-by: Nicholas Troast --- drivers/power/power_supply_sysfs.c | 1 - drivers/power/supply/qcom/qpnp-smb2.c | 4 ++++ drivers/power/supply/qcom/smb-lib.c | 25 +++++++++++++++------ drivers/power/supply/qcom/smb-lib.h | 2 +- drivers/power/supply/qcom/smb-reg.h | 1 - drivers/power/supply/qcom/smb138x-charger.c | 6 ++--- include/linux/power_supply.h | 1 - 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 8f5a85961a6b..3a43ae666456 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -286,7 +286,6 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(fcc_delta), POWER_SUPPLY_ATTR(icl_reduction), POWER_SUPPLY_ATTR(parallel_mode), - POWER_SUPPLY_ATTR(connector_therm_zone), POWER_SUPPLY_ATTR(die_health), POWER_SUPPLY_ATTR(connector_health), /* Local extensions of type int64_t */ diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 73ccb9a0bb7d..a5575eead7ec 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -832,6 +832,7 @@ static enum power_supply_property smb2_batt_props[] = { POWER_SUPPLY_PROP_CHARGE_DONE, POWER_SUPPLY_PROP_PARALLEL_DISABLE, POWER_SUPPLY_PROP_SET_SHIP_MODE, + POWER_SUPPLY_PROP_DIE_HEALTH, }; static int smb2_batt_get_prop(struct power_supply *psy, @@ -908,6 +909,9 @@ static int smb2_batt_get_prop(struct power_supply *psy, /* Not in ship mode as long as device is active */ val->intval = 0; break; + case POWER_SUPPLY_PROP_DIE_HEALTH: + rc = smblib_get_prop_die_health(chg, val); + break; default: pr_err("batt power supply prop %d not supported\n", psp); return -EINVAL; diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index c5714fb4b4cb..f56c70beb5f0 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -2027,10 +2027,10 @@ int smblib_get_pe_start(struct smb_charger *chg, return 0; } -int smblib_get_prop_connector_therm_zone(struct smb_charger *chg, +int smblib_get_prop_die_health(struct smb_charger *chg, union power_supply_propval *val) { - int rc, i; + int rc; u8 stat; rc = smblib_read(chg, TEMP_RANGE_STATUS_REG, &stat); @@ -2040,13 +2040,24 @@ int smblib_get_prop_connector_therm_zone(struct smb_charger *chg, return rc; } - i = fls((stat & TEMP_RANGE_MASK) >> TEMP_RANGE_SHIFT) - 1; - if (i < 0) { - smblib_err(chg, "TEMP_RANGE is invalid\n"); - return -EINVAL; + /* TEMP_RANGE bits are mutually exclusive */ + switch (stat & TEMP_RANGE_MASK) { + case TEMP_BELOW_RANGE_BIT: + val->intval = POWER_SUPPLY_HEALTH_COOL; + break; + case TEMP_WITHIN_RANGE_BIT: + val->intval = POWER_SUPPLY_HEALTH_WARM; + break; + case TEMP_ABOVE_RANGE_BIT: + val->intval = POWER_SUPPLY_HEALTH_HOT; + break; + case ALERT_LEVEL_BIT: + val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; + break; + default: + val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; } - val->intval = i; return 0; } diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index 8b130d7c4f1f..1a5ea25848c9 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -384,7 +384,7 @@ int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_charger_temp_max(struct smb_charger *chg, union power_supply_propval *val); -int smblib_get_prop_connector_therm_zone(struct smb_charger *chg, +int smblib_get_prop_die_health(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pd_current_max(struct smb_charger *chg, const union power_supply_propval *val); diff --git a/drivers/power/supply/qcom/smb-reg.h b/drivers/power/supply/qcom/smb-reg.h index f238b055d271..e005a27e8dd9 100644 --- a/drivers/power/supply/qcom/smb-reg.h +++ b/drivers/power/supply/qcom/smb-reg.h @@ -825,7 +825,6 @@ enum { #define THERM_REG_ACTIVE_BIT BIT(6) #define TLIM_BIT BIT(5) #define TEMP_RANGE_MASK GENMASK(4, 1) -#define TEMP_RANGE_SHIFT 1 #define ALERT_LEVEL_BIT BIT(4) #define TEMP_ABOVE_RANGE_BIT BIT(3) #define TEMP_WITHIN_RANGE_BIT BIT(2) diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c index 9287b7c37b97..1bdae492f44c 100644 --- a/drivers/power/supply/qcom/smb138x-charger.c +++ b/drivers/power/supply/qcom/smb138x-charger.c @@ -432,7 +432,7 @@ static enum power_supply_property smb138x_parallel_props[] = { POWER_SUPPLY_PROP_CHARGER_TEMP_MAX, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_PARALLEL_MODE, - POWER_SUPPLY_PROP_CONNECTOR_THERM_ZONE, + POWER_SUPPLY_PROP_CONNECTOR_HEALTH, }; static int smb138x_parallel_get_prop(struct power_supply *psy, @@ -485,8 +485,8 @@ static int smb138x_parallel_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PARALLEL_MODE: val->intval = POWER_SUPPLY_PARALLEL_MID_MID; break; - case POWER_SUPPLY_PROP_CONNECTOR_THERM_ZONE: - rc = smblib_get_prop_connector_therm_zone(chg, val); + case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: + rc = smblib_get_prop_die_health(chg, val); break; default: pr_err("parallel power supply get prop %d not supported\n", diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index fe529be52980..ee87e77e1b16 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -238,7 +238,6 @@ enum power_supply_property { POWER_SUPPLY_PROP_FCC_DELTA, POWER_SUPPLY_PROP_ICL_REDUCTION, POWER_SUPPLY_PROP_PARALLEL_MODE, - POWER_SUPPLY_PROP_CONNECTOR_THERM_ZONE, POWER_SUPPLY_PROP_DIE_HEALTH, POWER_SUPPLY_PROP_CONNECTOR_HEALTH, /* Local extensions of type int64_t */ From fcc57cd62fa19d916fdcca66df3bbf09ebb62c56 Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Sun, 5 Feb 2017 19:44:33 -0800 Subject: [PATCH 2/3] power_supply: add CTM_CURRENT_MAX property POWER_SUPPLY_PROP_CTM_CURRENT_MAX is needed by CTM to limit USB input current. Add it. Change-Id: I8aac65a91959300676cf7e1c2685a557f322c509 Signed-off-by: Nicholas Troast --- drivers/power/power_supply_sysfs.c | 1 + include/linux/power_supply.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 3a43ae666456..a9bb96df56c9 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -288,6 +288,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(parallel_mode), POWER_SUPPLY_ATTR(die_health), POWER_SUPPLY_ATTR(connector_health), + POWER_SUPPLY_ATTR(ctm_current_max), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index ee87e77e1b16..41568e45c024 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -240,6 +240,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_PARALLEL_MODE, POWER_SUPPLY_PROP_DIE_HEALTH, POWER_SUPPLY_PROP_CONNECTOR_HEALTH, + POWER_SUPPLY_PROP_CTM_CURRENT_MAX, /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ From 578f8f6a7c149a06925604b7002aeffc484f0129 Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Thu, 9 Feb 2017 10:05:03 -0800 Subject: [PATCH 3/3] qpnp-smb2: support POWER_SUPPLY_PROP_CTM_CURRENT_MAX CTM needs to vote for USB ICL. Add support for it. Change-Id: I88b146000f7327cf5dc7310fb721309f08dc3035 Signed-off-by: Nicholas Troast --- drivers/power/supply/qcom/qpnp-smb2.c | 9 +++++++++ drivers/power/supply/qcom/smb-lib.h | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index a5575eead7ec..125a39b66215 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -412,6 +412,7 @@ static enum power_supply_property smb2_usb_props[] = { POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, POWER_SUPPLY_PROP_BOOST_CURRENT, POWER_SUPPLY_PROP_PE_START, + POWER_SUPPLY_PROP_CTM_CURRENT_MAX, }; static int smb2_usb_get_prop(struct power_supply *psy, @@ -497,6 +498,9 @@ static int smb2_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PE_START: rc = smblib_get_pe_start(chg, val); break; + case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: + val->intval = get_client_vote(chg->usb_icl_votable, CTM_VOTER); + break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; @@ -545,6 +549,10 @@ static int smb2_usb_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_BOOST_CURRENT: rc = smblib_set_prop_boost_current(chg, val); break; + case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: + rc = vote(chg->usb_icl_votable, CTM_VOTER, + val->intval >= 0, val->intval); + break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; @@ -559,6 +567,7 @@ static int smb2_usb_prop_is_writeable(struct power_supply *psy, { switch (psp) { case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: + case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: return 1; default: break; diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index 1a5ea25848c9..864e7d691a43 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -55,6 +55,7 @@ enum print_reason { #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 CTM_VOTER "CTM_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3