From 513ad2ae53eff4997f95188df1a547a0f539ef3f Mon Sep 17 00:00:00 2001 From: Ryan Lattrel Date: Thu, 12 Dec 2019 11:35:42 -0600 Subject: [PATCH] p938x_charger: read current limits from dt Read the bpp and epp current and voltage limits from the device tree, and use the guaranteed power instead of the potential power to set them. Also use dc current now and dc current max so we don't have a race with AICL. Change-Id: Ic100e8e84ba2cf7a30095645b32ce573f2b0e47f Signed-off-by: Ryan Lattrel Reviewed-on: https://gerrit.mot.com/1471116 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Ling Jin Submit-Approved: Jira Key --- drivers/power/p938x_charger/p938x_charger.c | 106 +++++++++++++++----- 1 file changed, 81 insertions(+), 25 deletions(-) diff --git a/drivers/power/p938x_charger/p938x_charger.c b/drivers/power/p938x_charger/p938x_charger.c index c0b43e3caa85..884f54c1bc5b 100644 --- a/drivers/power/p938x_charger/p938x_charger.c +++ b/drivers/power/p938x_charger/p938x_charger.c @@ -216,6 +216,11 @@ module_param_named( debug_mask, __debug_mask, int, S_IRUSR | S_IWUSR ); +struct p938x_limits { + u32 tx_capability_mw; + u32 idc_max_ma; +}; + struct p938x_charger { const char *name; int *debug_mask; @@ -257,6 +262,12 @@ struct p938x_charger { struct wakeup_source wls_wake_source; bool epp_mode; + u32 bpp_current_limit; + struct p938x_limits *epp_current_limits; + int epp_limit_num; + u32 bpp_voltage; + u32 epp_voltage; + u8 fod_array_bpp[FOD_MAX_LEN]; u8 fod_array_epp[FOD_MAX_LEN]; u8 fod_array_tx[FOD_MAX_LEN]; @@ -267,20 +278,6 @@ struct p938x_charger { u8 q_factor; }; -struct p938x_limits { - unsigned int tx_capability_mw; - unsigned long idc_max_ma; -}; - -/* Lowest mW first, highest mW last */ -static struct p938x_limits p938x_epp_limits[] = { - {10000, 850}, - {15000, 1250}, -}; - -static const int p938x_epp_limit_num = - sizeof(p938x_epp_limits) / sizeof(struct p938x_limits); - #define WLS_FLAG_BOOST_ENABLED 0 #define WLS_FLAG_TX_ATTACHED 1 #define WLS_FLAG_KEEP_AWAKE 2 @@ -770,7 +767,7 @@ static int p938x_set_dc_max_icl_ma(struct p938x_charger *chip, unsigned int idc) { union power_supply_propval val; - p938x_dbg(chip, PR_MOTO, "Setting IDC to %u mA\n", idc); + p938x_dbg(chip, PR_MOTO, "Setting IDC max to %u mA\n", idc); idc *= 1000; /* Convert to uA */ val.intval = idc; @@ -780,6 +777,20 @@ static int p938x_set_dc_max_icl_ma(struct p938x_charger *chip, unsigned int idc) val); } +static int p938x_set_dc_now_icl_ma(struct p938x_charger *chip, unsigned int idc) +{ + union power_supply_propval val; + + p938x_dbg(chip, PR_MOTO, "Setting IDC to %u mA\n", idc); + + idc *= 1000; /* Convert to uA */ + val.intval = idc; + + return p938x_set_dc_psp_prop(chip, + POWER_SUPPLY_PROP_CURRENT_NOW, + val); +} + static int p938x_program_fod(struct p938x_charger *chip, u8 *array, int array_len) { @@ -1182,7 +1193,7 @@ static int p938x_check_system_mode(struct p938x_charger *chip) u8 mode = 0; int tx_guaranteed; int tx_potential; - struct p938x_limits epp_limit = p938x_epp_limits[0]; + struct p938x_limits epp_limit; rc = p938x_read_buffer(chip, SYS_MODE_REG, &mode, 1); if (rc < 0) @@ -1200,7 +1211,8 @@ static int p938x_check_system_mode(struct p938x_charger *chip) p938x_dbg(chip, PR_INTERRUPT, "MODE: SYS_MODE_EXTENDED\n"); chip->epp_mode = true; - if (!p938x_get_tx_capability(chip, &tx_guaranteed, &tx_potential)) { + if (chip->epp_limit_num && + !p938x_get_tx_capability(chip, &tx_guaranteed, &tx_potential)) { p938x_dbg(chip, PR_INTERRUPT, "EPP GUARANTEED %dmW, POTENTIAL %dmW\n", tx_guaranteed, tx_potential); @@ -1208,28 +1220,29 @@ static int p938x_check_system_mode(struct p938x_charger *chip) * and go backwards, if we find one more appropriate use that one * instead */ - for(i=p938x_epp_limit_num-1; i >= 0; i--) { - if(tx_potential >= p938x_epp_limits[i].tx_capability_mw) { - epp_limit = p938x_epp_limits[i]; + epp_limit = chip->epp_current_limits[0]; + for(i=chip->epp_limit_num-1; i >= 0; i--) { + if(tx_guaranteed >= chip->epp_current_limits[i].tx_capability_mw) { + epp_limit = chip->epp_current_limits[i]; break; } } - p938x_dbg(chip, PR_INTERRUPT, "EPP LIMIT is %d mW -> %lu mA\n", + p938x_dbg(chip, PR_INTERRUPT, "EPP LIMIT is %d mW -> %d mA\n", epp_limit.tx_capability_mw, epp_limit.idc_max_ma); p938x_set_dc_max_icl_ma(chip, epp_limit.idc_max_ma); } else p938x_set_dc_max_icl_ma(chip, EPP_MAX_IDC); - p938x_set_rx_vout(chip, EPP_MAX_VOUT); + p938x_set_rx_vout(chip, chip->epp_voltage); p938x_set_rx_ocl(chip, EPP_MAX_IOUT); p938x_program_fod(chip, chip->fod_array_epp, chip->fod_array_epp_len); } else { chip->epp_mode = false; - p938x_set_dc_max_icl_ma(chip, BPP_MAX_IDC); - p938x_set_rx_vout(chip, BPP_MAX_VOUT); + p938x_set_dc_max_icl_ma(chip, chip->bpp_current_limit); + p938x_set_rx_vout(chip, chip->bpp_voltage); p938x_set_rx_ocl(chip, BPP_MAX_IOUT); p938x_program_fod(chip, chip->fod_array_bpp, chip->fod_array_bpp_len); @@ -1501,6 +1514,7 @@ static ssize_t force_idc_store(struct device *dev, /* Store to persist change */ chip->wls_idc_max = value; + p938x_set_dc_now_icl_ma(chip, value); p938x_set_dc_max_icl_ma(chip, value); return r ? r : count; @@ -1822,7 +1836,8 @@ static ssize_t tx_capability_show(struct device *dev, if (chip->epp_mode) { if (!p938x_get_tx_capability(chip, &tx_guaranteed, &tx_potential)) - return scnprintf(buf, WLS_SHOW_MAX_SIZE, "EPP %dmW\n", tx_potential); + return scnprintf(buf, WLS_SHOW_MAX_SIZE, "EPP %dmW (Potential %dmW)\n", + tx_guaranteed, tx_potential); else return scnprintf(buf, WLS_SHOW_MAX_SIZE, "EPP Unknown\n"); } else @@ -2054,6 +2069,8 @@ static int p938x_parse_dt(struct p938x_charger *chip) struct device_node *node = chip->dev->of_node; int rc; unsigned tmp; + int byte_len; + int i; if (!node) { p938x_err(chip, "device tree info. missing\n"); @@ -2133,6 +2150,45 @@ static int p938x_parse_dt(struct p938x_charger *chip) chip->q_factor = tmp; } + if (of_find_property(node, "epp-current-table", &byte_len)) { + chip->epp_current_limits = (struct p938x_limits *) + devm_kzalloc(chip->dev, byte_len, GFP_KERNEL); + + if (chip->epp_current_limits == NULL) + return -ENOMEM; + + rc = of_property_read_u32_array(node, + "epp-current-table", + (u32 *)chip->epp_current_limits, + byte_len / sizeof(u32)); + if (rc < 0) { + p938x_err(chip, "Couldn't read epp current limits rc = %d\n", rc); + return rc; + } + + chip->epp_limit_num = + byte_len / sizeof(struct p938x_limits); + + p938x_dbg(chip, PR_IMPORTANT, "epp current limits: Num: %d\n", chip->epp_limit_num); + for (i = 0; i < chip->epp_limit_num; i++) { + p938x_dbg(chip, PR_IMPORTANT, "epp current limit: %dW, %dmA", + chip->epp_current_limits[i].tx_capability_mw / 1000, + chip->epp_current_limits[i].idc_max_ma); + } + } + + rc = of_property_read_u32(node, "epp-voltage", &chip->epp_voltage); + if (rc) + chip->epp_voltage = EPP_MAX_VOUT; + + rc = of_property_read_u32(node, "bpp-current", &chip->bpp_current_limit); + if (rc) + chip->bpp_current_limit = BPP_MAX_IDC; + + rc = of_property_read_u32(node, "bpp-voltage", &chip->bpp_voltage); + if (rc) + chip->bpp_voltage = BPP_MAX_VOUT; + return 0; }