Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4da3df9c authored by Anirudh Ghayal's avatar Anirudh Ghayal Committed by Harry Yang
Browse files

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: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 1bcb8a57
Loading
Loading
Loading
Loading
+36 −3
Original line number Diff line number Diff line
@@ -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;
	}

+78 −46
Original line number Diff line number Diff line
@@ -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) {
@@ -2014,8 +2038,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)
{
@@ -2023,7 +2045,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;
@@ -2655,7 +2678,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,
@@ -2761,16 +2785,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;
		}
	}
@@ -2785,14 +2813,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);
	}
}

@@ -2993,7 +3024,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;
}

+13 −0
Original line number Diff line number Diff line
@@ -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;
@@ -157,6 +167,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;
@@ -261,6 +272,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);
+4 −0
Original line number Diff line number Diff line
@@ -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)
@@ -1009,4 +1010,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 */