qpnp: smb2: Add charger frequency config for PM660
The clock to the PM660 charger has to be configured in the CHG_FREQ module instead of CHG_MISC. Also, the charger frequencies for PM660 and PMI8998 are different, add logic to handle that. CRs-Fixed: 1104287 Change-Id: I5f4daf9354b209226a03b4f8026e20be8a73348b Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
This commit is contained in:
parent
20e1ed9259
commit
6e1f3205b4
4 changed files with 131 additions and 49 deletions
|
@ -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;
|
||||
|
@ -1515,7 +1532,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;
|
||||
|
@ -1545,9 +1562,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",
|
||||
|
@ -1936,10 +1969,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
@ -1991,8 +2015,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)
|
||||
{
|
||||
|
@ -2000,7 +2022,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;
|
||||
|
@ -2632,7 +2655,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,
|
||||
|
@ -2738,16 +2762,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;
|
||||
}
|
||||
}
|
||||
|
@ -2762,14 +2790,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2966,7 +2997,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,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;
|
||||
|
@ -154,6 +164,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;
|
||||
|
@ -258,6 +269,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);
|
||||
|
|
|
@ -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)
|
||||
|
@ -1007,4 +1008,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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue