diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2017-02-09 03:11:52 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-02-09 03:11:51 -0800 |
| commit | 91b231673d5c6ef00469eaefc5f4310ab2e982af (patch) | |
| tree | 9f7118704cdd639374e7b75993b3eb5bd1f5ffed /drivers/power | |
| parent | 2d3372a5f8dea7765e04ed7eb4f9c9aa5499f001 (diff) | |
| parent | 6e1f3205b4356b12948e135d72b559e7a9d6963b (diff) | |
Merge "qpnp: smb2: Add charger frequency config for PM660"
Diffstat (limited to 'drivers/power')
| -rw-r--r-- | drivers/power/supply/qcom/qpnp-smb2.c | 39 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 124 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.h | 13 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-reg.h | 4 |
4 files changed, 131 insertions, 49 deletions
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index f8171ecc47f3..4e9d2894479a 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -219,6 +219,23 @@ static struct smb_params v1_params = { }, }; +static struct smb_params pm660_params = { + .freq_buck = { + .name = "buck switching frequency", + .reg = FREQ_CLK_DIV_REG, + .min_u = 600, + .max_u = 1600, + .set_proc = smblib_set_chg_freq, + }, + .freq_boost = { + .name = "boost switching frequency", + .reg = FREQ_CLK_DIV_REG, + .min_u = 600, + .max_u = 1600, + .set_proc = smblib_set_chg_freq, + }, +}; + #define STEP_CHARGING_MAX_STEPS 5 struct smb_dt_props { int fcc_ua; @@ -1530,7 +1547,7 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } -static int smb2_setup_wa_flags(struct smb2 *chip) +static int smb2_chg_config_init(struct smb2 *chip) { struct smb_charger *chg = &chip->chg; struct pmic_revid_data *pmic_rev_id; @@ -1560,9 +1577,25 @@ static int smb2_setup_wa_flags(struct smb2 *chip) chg->wa_flags |= QC_CHARGER_DETECTION_WA_BIT; if (pmic_rev_id->rev4 == PMI8998_V2P0_REV4) /* PMI rev 2.0 */ chg->wa_flags |= TYPEC_CC2_REMOVAL_WA_BIT; + chg->chg_freq.freq_5V = 600; + chg->chg_freq.freq_6V_8V = 800; + chg->chg_freq.freq_9V = 1000; + chg->chg_freq.freq_12V = 1200; + chg->chg_freq.freq_removal = 1000; + chg->chg_freq.freq_below_otg_threshold = 2000; + chg->chg_freq.freq_above_otg_threshold = 800; break; case PM660_SUBTYPE: chip->chg.wa_flags |= BOOST_BACK_WA; + chg->param.freq_buck = pm660_params.freq_buck; + chg->param.freq_boost = pm660_params.freq_boost; + chg->chg_freq.freq_5V = 600; + chg->chg_freq.freq_6V_8V = 800; + chg->chg_freq.freq_9V = 1050; + chg->chg_freq.freq_12V = 1200; + chg->chg_freq.freq_removal = 1050; + chg->chg_freq.freq_below_otg_threshold = 1600; + chg->chg_freq.freq_above_otg_threshold = 800; break; default: pr_err("PMIC subtype %d not supported\n", @@ -1951,10 +1984,10 @@ static int smb2_probe(struct platform_device *pdev) return -EINVAL; } - rc = smb2_setup_wa_flags(chip); + rc = smb2_chg_config_init(chip); if (rc < 0) { if (rc != -EPROBE_DEFER) - pr_err("Couldn't setup wa flags rc=%d\n", rc); + pr_err("Couldn't setup chg_config rc=%d\n", rc); return rc; } diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index ee5b5a51465b..16edf875de96 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -39,7 +39,7 @@ static bool is_secure(struct smb_charger *chg, int addr) { - if (addr == SHIP_MODE_REG) + if (addr == SHIP_MODE_REG || addr == FREQ_CLK_DIV_REG) return true; /* assume everything above 0xA0 is secure */ return (bool)((addr & 0xFF) >= 0xA0); @@ -193,34 +193,6 @@ int smblib_get_usb_suspend(struct smb_charger *chg, int *suspend) return rc; } -#define FSW_600HZ_FOR_5V 600 -#define FSW_800HZ_FOR_6V_8V 800 -#define FSW_1MHZ_FOR_REMOVAL 1000 -#define FSW_1MHZ_FOR_9V 1000 -#define FSW_1P2MHZ_FOR_12V 1200 -static int smblib_set_opt_freq_buck(struct smb_charger *chg, int fsw_khz) -{ - union power_supply_propval pval = {0, }; - int rc = 0; - - rc = smblib_set_charge_param(chg, &chg->param.freq_buck, fsw_khz); - if (rc < 0) - dev_err(chg->dev, "Error in setting freq_buck rc=%d\n", rc); - - if (chg->mode == PARALLEL_MASTER && chg->pl.psy) { - pval.intval = fsw_khz; - rc = power_supply_set_property(chg->pl.psy, - POWER_SUPPLY_PROP_BUCK_FREQ, &pval); - if (rc < 0) { - dev_err(chg->dev, - "Could not set parallel buck_freq rc=%d\n", rc); - return rc; - } - } - - return rc; -} - struct apsd_result { const char * const name; const u8 bit; @@ -325,6 +297,58 @@ static const struct apsd_result *smblib_get_apsd_result(struct smb_charger *chg) * REGISTER SETTERS * ********************/ +static int chg_freq_list[] = { + 9600, 9600, 6400, 4800, 3800, 3200, 2700, 2400, 2100, 1900, 1700, + 1600, 1500, 1400, 1300, 1200, +}; + +int smblib_set_chg_freq(struct smb_chg_param *param, + int val_u, u8 *val_raw) +{ + u8 i; + + if (val_u > param->max_u || val_u < param->min_u) + return -EINVAL; + + /* Charger FSW is the configured freqency / 2 */ + val_u *= 2; + for (i = 0; i < ARRAY_SIZE(chg_freq_list); i++) { + if (chg_freq_list[i] == val_u) + break; + } + if (i == ARRAY_SIZE(chg_freq_list)) { + pr_err("Invalid frequency %d Hz\n", val_u / 2); + return -EINVAL; + } + + *val_raw = i; + + return 0; +} + +static int smblib_set_opt_freq_buck(struct smb_charger *chg, int fsw_khz) +{ + union power_supply_propval pval = {0, }; + int rc = 0; + + rc = smblib_set_charge_param(chg, &chg->param.freq_buck, fsw_khz); + if (rc < 0) + dev_err(chg->dev, "Error in setting freq_buck rc=%d\n", rc); + + if (chg->mode == PARALLEL_MASTER && chg->pl.psy) { + pval.intval = fsw_khz; + rc = power_supply_set_property(chg->pl.psy, + POWER_SUPPLY_PROP_BUCK_FREQ, &pval); + if (rc < 0) { + dev_err(chg->dev, + "Could not set parallel buck_freq rc=%d\n", rc); + return rc; + } + } + + return rc; +} + int smblib_set_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int val_u) { @@ -417,13 +441,13 @@ static int smblib_set_usb_pd_allowed_voltage(struct smb_charger *chg, if (min_allowed_uv == MICRO_5V && max_allowed_uv == MICRO_5V) { allowed_voltage = USBIN_ADAPTER_ALLOW_5V; - smblib_set_opt_freq_buck(chg, FSW_600HZ_FOR_5V); + smblib_set_opt_freq_buck(chg, chg->chg_freq.freq_5V); } else if (min_allowed_uv == MICRO_9V && max_allowed_uv == MICRO_9V) { allowed_voltage = USBIN_ADAPTER_ALLOW_9V; - smblib_set_opt_freq_buck(chg, FSW_1MHZ_FOR_9V); + smblib_set_opt_freq_buck(chg, chg->chg_freq.freq_9V); } else if (min_allowed_uv == MICRO_12V && max_allowed_uv == MICRO_12V) { allowed_voltage = USBIN_ADAPTER_ALLOW_12V; - smblib_set_opt_freq_buck(chg, FSW_1P2MHZ_FOR_12V); + smblib_set_opt_freq_buck(chg, chg->chg_freq.freq_12V); } else if (min_allowed_uv < MICRO_9V && max_allowed_uv <= MICRO_9V) { allowed_voltage = USBIN_ADAPTER_ALLOW_5V_TO_9V; } else if (min_allowed_uv < MICRO_9V && max_allowed_uv <= MICRO_12V) { @@ -1981,8 +2005,6 @@ int smblib_set_prop_usb_current_max(struct smb_charger *chg, return rc; } -#define FSW_2MHZ 2000 -#define FSW_800KHZ_RESET 800 int smblib_set_prop_boost_current(struct smb_charger *chg, const union power_supply_propval *val) { @@ -1990,7 +2012,8 @@ int smblib_set_prop_boost_current(struct smb_charger *chg, rc = smblib_set_charge_param(chg, &chg->param.freq_boost, val->intval <= chg->boost_threshold_ua ? - FSW_2MHZ : FSW_800KHZ_RESET); + chg->chg_freq.freq_below_otg_threshold : + chg->chg_freq.freq_above_otg_threshold); if (rc < 0) { dev_err(chg->dev, "Error in setting freq_boost rc=%d\n", rc); return rc; @@ -2581,7 +2604,8 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data) vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT); smblib_set_opt_freq_buck(chg, - vbus_rising ? FSW_600HZ_FOR_5V : FSW_1MHZ_FOR_REMOVAL); + vbus_rising ? chg->chg_freq.freq_5V : + chg->chg_freq.freq_removal); /* fetch the DPDM regulator */ if (!chg->dpdm_reg && of_get_property(chg->dev->of_node, @@ -2687,16 +2711,20 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) switch (stat & QC_2P0_STATUS_MASK) { case QC_5V_BIT: - smblib_set_opt_freq_buck(chg, FSW_600HZ_FOR_5V); + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_5V); break; case QC_9V_BIT: - smblib_set_opt_freq_buck(chg, FSW_1MHZ_FOR_9V); + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_9V); break; case QC_12V_BIT: - smblib_set_opt_freq_buck(chg, FSW_1P2MHZ_FOR_12V); + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_12V); break; default: - smblib_set_opt_freq_buck(chg, FSW_1MHZ_FOR_REMOVAL); + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_removal); break; } } @@ -2711,14 +2739,17 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) pulses = (stat & QC_PULSE_COUNT_MASK); if (pulses < QC3_PULSES_FOR_6V) - smblib_set_opt_freq_buck(chg, FSW_600HZ_FOR_5V); + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_5V); else if (pulses < QC3_PULSES_FOR_9V) - smblib_set_opt_freq_buck(chg, FSW_800HZ_FOR_6V_8V); + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_6V_8V); else if (pulses < QC3_PULSES_FOR_12V) - smblib_set_opt_freq_buck(chg, FSW_1MHZ_FOR_9V); + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_9V); else - smblib_set_opt_freq_buck(chg, FSW_1P2MHZ_FOR_12V); - + smblib_set_opt_freq_buck(chg, + chg->chg_freq.freq_12V); } } @@ -2915,7 +2946,8 @@ static void typec_sink_insertion(struct smb_charger *chg) static void typec_sink_removal(struct smb_charger *chg) { - smblib_set_charge_param(chg, &chg->param.freq_boost, FSW_800KHZ_RESET); + smblib_set_charge_param(chg, &chg->param.freq_boost, + chg->chg_freq.freq_above_otg_threshold); chg->boost_current_ua = 0; } diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index cda4b80939ec..e341484bc2ec 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -105,6 +105,16 @@ struct smb_chg_param { u8 *val_raw); }; +struct smb_chg_freq { + unsigned int freq_5V; + unsigned int freq_6V_8V; + unsigned int freq_9V; + unsigned int freq_12V; + unsigned int freq_removal; + unsigned int freq_below_otg_threshold; + unsigned int freq_above_otg_threshold; +}; + struct smb_params { struct smb_chg_param fcc; struct smb_chg_param fv; @@ -158,6 +168,7 @@ struct smb_charger { int *debug_mask; enum smb_mode mode; bool external_vconn; + struct smb_chg_freq chg_freq; /* locks */ struct mutex write_lock; @@ -264,6 +275,8 @@ int smblib_mapping_cc_delta_to_field_value(struct smb_chg_param *param, u8 val_raw); int smblib_mapping_cc_delta_from_field_value(struct smb_chg_param *param, int val_u, u8 *val_raw); +int smblib_set_chg_freq(struct smb_chg_param *param, + int val_u, u8 *val_raw); int smblib_vbus_regulator_enable(struct regulator_dev *rdev); int smblib_vbus_regulator_disable(struct regulator_dev *rdev); diff --git a/drivers/power/supply/qcom/smb-reg.h b/drivers/power/supply/qcom/smb-reg.h index b5de39de995a..f238b055d271 100644 --- a/drivers/power/supply/qcom/smb-reg.h +++ b/drivers/power/supply/qcom/smb-reg.h @@ -21,6 +21,7 @@ #define USBIN_BASE 0x1300 #define DCIN_BASE 0x1400 #define MISC_BASE 0x1600 +#define CHGR_FREQ_BASE 0x1900 #define PERPH_TYPE_OFFSET 0x04 #define TYPE_MASK GENMASK(7, 0) @@ -1015,4 +1016,7 @@ enum { #define CFG_BUCKBOOST_FREQ_SELECT_BUCK_REG (MISC_BASE + 0xA0) #define CFG_BUCKBOOST_FREQ_SELECT_BOOST_REG (MISC_BASE + 0xA1) +/* CHGR FREQ Peripheral registers */ +#define FREQ_CLK_DIV_REG (CHGR_FREQ_BASE + 0x50) + #endif /* __SMB2_CHARGER_REG_H */ |
