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

Commit b0f1deac authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: smb5: add support for die/connector temp based mitigation"

parents c7878be2 0de6fb91
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -201,6 +201,25 @@ Charger specific properties:
	Definition: Phandle for the VADC node, it is used to obtain USBIN_V
		    and USBIN_I readings on PMIC632 based platform.

- qcom,hw-die-temp-mitigation
	Usage:      optional
	Value type: bool
	Definition: Boolean flag which when present enables h/w based thermal
		    mitigation.

- qcom,hw-connector-mitigation
	Usage:      optional
	Value type: bool
	Definition: Boolean flag which when present enables h/w based
		    connector temperature mitigation.

- qcom,connector-internal-pull-kohm
	Usage:      optional
	Value type: <u32>
	Definition: Specifies internal pull-up configuration to be applied to
		    connector THERM, only valid values are (0/30/100/400).
		    If not specified 100K is used as default pull-up.

=============================================
Second Level Nodes - SMB5 Charger Peripherals
=============================================
+127 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ static struct smb_params smb5_pmi632_params = {
	},
	.icl_stat		= {
		.name   = "input current limit status",
		.reg    = AICL_ICL_STATUS_REG,
		.reg    = ICL_STATUS_REG,
		.min_u  = 0,
		.max_u  = 3000000,
		.step_u = 50000,
@@ -206,6 +206,13 @@ enum {
	USBIN_VOLTAGE,
};

enum {
	BAT_THERM = 0,
	MISC_THERM,
	CONN_THERM,
	SMB_THERM,
};

#define PMI632_MAX_ICL_UA	3000000
static int smb5_chg_config_init(struct smb5 *chip)
{
@@ -266,6 +273,53 @@ static int smb5_chg_config_init(struct smb5 *chip)
	return rc;
}

#define PULL_NO_PULL	0
#define PULL_30K	30
#define PULL_100K	100
#define PULL_400K	400
static int get_valid_pullup(int pull_up)
{
	int pull;

	/* pull up can only be 0/30K/100K/400K) */
	switch (pull_up) {
	case PULL_NO_PULL:
		pull = INTERNAL_PULL_NO_PULL;
		break;
	case PULL_30K:
		pull = INTERNAL_PULL_30K_PULL;
		break;
	case PULL_100K:
		pull = INTERNAL_PULL_100K_PULL;
		break;
	case PULL_400K:
		pull = INTERNAL_PULL_400K_PULL;
		break;
	default:
		pull = INTERNAL_PULL_100K_PULL;
	}

	return pull;
}

#define INTERNAL_PULL_UP_MASK	0x3
static int smb5_configure_internal_pull(struct smb_charger *chg, int type,
					int pull)
{
	int rc;
	int shift = type * 2;
	u8 mask = INTERNAL_PULL_UP_MASK << shift;
	u8 val = pull << shift;

	rc = smblib_masked_write(chg, BATIF_ADC_INTERNAL_PULL_UP_REG,
				mask, val);
	if (rc < 0)
		dev_err(chg->dev,
			"Couldn't configure ADC pull-up reg rc=%d\n", rc);

	return rc;
}

#define MICRO_1P5A		1500000
#define MICRO_1PA		1000000
#define MICRO_P1A		100000
@@ -387,6 +441,16 @@ static int smb5_parse_dt(struct smb5 *chip)
	if (rc < 0)
		chg->otg_delay_ms = OTG_DEFAULT_DEGLITCH_TIME_MS;

	chg->hw_die_temp_mitigation = of_property_read_bool(node,
					"qcom,hw-die-temp-mitigation");

	chg->hw_connector_mitigation = of_property_read_bool(node,
					"qcom,hw-connector-mitigation");

	chg->connector_pull_up = -EINVAL;
	of_property_read_u32(node, "qcom,connector-internal-pull-kohm",
					&chg->connector_pull_up);

	return 0;
}

@@ -474,6 +538,7 @@ static enum power_supply_property smb5_usb_props[] = {
	POWER_SUPPLY_PROP_SCOPE,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
	POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED,
	POWER_SUPPLY_PROP_QC_OPTI_DISABLE,
};

static int smb5_usb_get_prop(struct power_supply *psy,
@@ -602,6 +667,13 @@ static int smb5_usb_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED:
		val->intval = !chg->flash_active;
		break;
	case POWER_SUPPLY_PROP_QC_OPTI_DISABLE:
		if (chg->hw_die_temp_mitigation)
			val->intval = POWER_SUPPLY_QC_THERMAL_BALANCE_DISABLE
					| POWER_SUPPLY_QC_INOV_THERMAL_DISABLE;
		if (chg->hw_connector_mitigation)
			val->intval |= POWER_SUPPLY_QC_CTM_DISABLE;
		break;
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
@@ -1534,6 +1606,42 @@ static int smb5_configure_micro_usb(struct smb_charger *chg)
	return rc;
}

static int smb5_configure_mitigation(struct smb_charger *chg)
{
	int rc;
	u8 chan = 0;

	if (!chg->hw_die_temp_mitigation && !chg->hw_connector_mitigation)
		return 0;

	if (chg->hw_die_temp_mitigation) {
		rc = smblib_write(chg, MISC_THERMREG_SRC_CFG_REG,
				THERMREG_CONNECTOR_ADC_SRC_EN_BIT
				| THERMREG_DIE_ADC_SRC_EN_BIT
				| THERMREG_DIE_CMP_SRC_EN_BIT);
		if (rc < 0) {
			dev_err(chg->dev,
				"Couldn't configure THERM_SRC reg rc=%d\n", rc);
			return rc;
		};

		chan = DIE_TEMP_CHANNEL_EN_BIT;
	}

	if (chg->hw_connector_mitigation)
		chan |= CONN_THM_CHANNEL_EN_BIT;

	rc = smblib_masked_write(chg, BATIF_ADC_CHANNEL_EN_REG,
			CONN_THM_CHANNEL_EN_BIT | DIE_TEMP_CHANNEL_EN_BIT,
			chan);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't enable ADC channelrc=%d\n", rc);
		return rc;
	}

	return 0;
}

static int smb5_init_hw(struct smb5 *chip)
{
	struct smb_charger *chg = &chip->chg;
@@ -1640,6 +1748,13 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;
	}

	/* configure temperature mitigation */
	rc = smb5_configure_mitigation(chg);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure mitigation rc=%d\n", rc);
		return rc;
	}

	/* vote 0mA on usb_icl for non battery platforms */
	vote(chg->usb_icl_votable,
		DEFAULT_VOTER, chip->dt.no_battery, 0);
@@ -1850,6 +1965,17 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;
	}

	if (chg->connector_pull_up != -EINVAL) {
		rc = smb5_configure_internal_pull(chg, CONN_THERM,
				get_valid_pullup(chg->connector_pull_up));
		if (rc < 0) {
			dev_err(chg->dev,
				"Couldn't configure CONN_THERM pull-up rc=%d\n",
				rc);
			return rc;
		}
	}

	return rc;
}

+19 −1
Original line number Diff line number Diff line
@@ -2109,7 +2109,7 @@ int smblib_get_prop_die_health(struct smb_charger *chg,
	int rc;
	u8 stat;

	rc = smblib_read(chg, TEMP_RANGE_STATUS_REG, &stat);
	rc = smblib_read(chg, MISC_TEMP_RANGE_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read TEMP_RANGE_STATUS_REG rc=%d\n",
									rc);
@@ -2691,6 +2691,24 @@ irqreturn_t icl_change_irq_handler(int irq, void *data)
	struct smb_charger *chg = irq_data->parent_data;

	if (chg->mode == PARALLEL_MASTER) {
		/*
		 * Ignore if change in ICL is due to DIE temp mitigation.
		 * This is to prevent any further ICL split.
		 */
		if (chg->hw_die_temp_mitigation) {
			rc = smblib_read(chg, MISC_DIE_TEMP_STATUS_REG, &stat);
			if (rc < 0) {
				smblib_err(chg,
					"Couldn't read DIE_TEMP rc=%d\n", rc);
				return IRQ_HANDLED;
			}
			if (stat & (DIE_TEMP_UB_BIT | DIE_TEMP_LB_BIT)) {
				smblib_dbg(chg, PR_PARALLEL,
					"skip ICL change DIE_TEMP %x\n", stat);
				return IRQ_HANDLED;
			}
		}

		rc = smblib_read(chg, AICL_STATUS_REG, &stat);
		if (rc < 0) {
			smblib_err(chg, "Couldn't read AICL_STATUS rc=%d\n",
+3 −0
Original line number Diff line number Diff line
@@ -360,6 +360,9 @@ struct smb_charger {
	int			auto_recharge_soc;
	bool			jeita_configured;
	enum sink_src_mode	sink_src_mode;
	bool			hw_die_temp_mitigation;
	bool			hw_connector_mitigation;
	int			connector_pull_up;

	/* workaround flag */
	u32			wa_flags;
+30 −2
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ enum {
 *  DCDC Peripheral Registers  *
 ********************************/
#define ICL_MAX_STATUS_REG			(DCDC_BASE + 0x06)

#define ICL_STATUS_REG				(DCDC_BASE + 0x07)
#define AICL_ICL_STATUS_REG			(DCDC_BASE + 0x08)

#define AICL_STATUS_REG				(DCDC_BASE + 0x0A)
@@ -146,6 +146,18 @@ enum {
#define SHIP_MODE_REG				(BATIF_BASE + 0x40)
#define SHIP_MODE_EN_BIT			BIT(0)

#define BATIF_ADC_CHANNEL_EN_REG		(BATIF_BASE + 0x82)
#define CONN_THM_CHANNEL_EN_BIT			BIT(4)
#define DIE_TEMP_CHANNEL_EN_BIT			BIT(2)

#define BATIF_ADC_INTERNAL_PULL_UP_REG		(BATIF_BASE + 0x86)
#define INTERNAL_PULL_UP_CONN_THM_MASK		GENMASK(5, 4)
#define CONN_THM_SHIFT				4
#define INTERNAL_PULL_NO_PULL			0x00
#define INTERNAL_PULL_30K_PULL			0x01
#define INTERNAL_PULL_100K_PULL			0x02
#define INTERNAL_PULL_400K_PULL			0x03

/********************************
 *  USBIN Peripheral Registers  *
 ********************************/
@@ -333,7 +345,7 @@ enum {
/********************************
 *  MISC Peripheral Registers  *
 ********************************/
#define TEMP_RANGE_STATUS_REG			(MISC_BASE + 0x06)
#define MISC_TEMP_RANGE_STATUS_REG		(MISC_BASE + 0x06)
#define THERM_REG_ACTIVE_BIT			BIT(6)
#define TLIM_BIT				BIT(5)
#define TEMP_RANGE_MASK				GENMASK(4, 1)
@@ -343,6 +355,12 @@ enum {
#define TEMP_BELOW_RANGE_BIT			BIT(1)
#define THERMREG_DISABLED_BIT			BIT(0)

#define MISC_DIE_TEMP_STATUS_REG		(MISC_BASE + 0x07)
#define DIE_TEMP_SHDN_BIT			BIT(3)
#define DIE_TEMP_RST_BIT			BIT(2)
#define DIE_TEMP_UB_BIT				BIT(1)
#define DIE_TEMP_LB_BIT				BIT(0)

#define BARK_BITE_WDOG_PET_REG			(MISC_BASE + 0x43)
#define BARK_BITE_WDOG_PET_BIT			BIT(0)

@@ -366,6 +384,16 @@ enum {
#define BARK_WDOG_TIMEOUT_MASK			GENMASK(3, 2)
#define BITE_WDOG_TIMEOUT_MASK			GENMASK(1, 0)

#define MISC_THERMREG_SRC_CFG_REG		(MISC_BASE + 0x70)
#define THERMREG_SW_ICL_ADJUST_BIT		BIT(7)
#define DIE_ADC_SEL_BIT				BIT(6)
#define THERMREG_SMB_ADC_SRC_EN_BIT		BIT(5)
#define THERMREG_CONNECTOR_ADC_SRC_EN_BIT	BIT(4)
#define SKIN_ADC_CFG_BIT			BIT(3)
#define THERMREG_SKIN_ADC_SRC_EN_BIT		BIT(2)
#define THERMREG_DIE_ADC_SRC_EN_BIT		BIT(1)
#define THERMREG_DIE_CMP_SRC_EN_BIT		BIT(0)

#define MISC_SMB_CFG_REG			(MISC_BASE + 0x90)
#define SMB_EN_SEL_BIT				BIT(4)
#define CP_EN_POLARITY_CFG_BIT			BIT(3)