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

Commit bcd92ec6 authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: smb5-lib: Report charger detection status



Use the CHARGER_STATUS to report the charger-detection status
and INPUT_VOLTAGE_SETTLED to report input voltage, reading them
from SDAM.

While at it, clear the SMB_EN for CP in the shutdown path
to prevent SMB from being enabled in the next boot.

Change-Id: I269b0be18b56d56c0ab0e68ee1d7194d09824dd7
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 4945d76d
Loading
Loading
Loading
Loading
+81 −1
Original line number Original line Diff line number Diff line
@@ -730,6 +730,46 @@ static int smb5_parse_dt_voltages(struct smb5 *chip, struct device_node *node)
	return 0;
	return 0;
}
}


static int smb5_parse_sdam(struct smb5 *chip, struct device_node *node)
{
	struct device_node *child;
	struct smb_charger *chg = &chip->chg;
	struct property *prop;
	const char *name;
	int rc;
	u32 base;
	u8 type;

	for_each_available_child_of_node(node, child) {
		of_property_for_each_string(child, "reg", prop, name) {
			rc = of_property_read_u32(child, "reg", &base);
			if (rc < 0) {
				pr_err("Failed to read base rc=%d\n", rc);
				return rc;
			}

			rc = smblib_read(chg, base + PERPH_TYPE_OFFSET, &type);
			if (rc < 0) {
				pr_err("Failed to read type rc=%d\n", rc);
				return rc;
			}

			switch (type) {
			case SDAM_TYPE:
				chg->sdam_base = base;
				break;
			default:
				break;
			}
		}
	}

	if (!chg->sdam_base)
		pr_debug("SDAM node not defined\n");

	return 0;
}

static int smb5_parse_dt(struct smb5 *chip)
static int smb5_parse_dt(struct smb5 *chip)
{
{
	struct smb_charger *chg = &chip->chg;
	struct smb_charger *chg = &chip->chg;
@@ -757,6 +797,10 @@ static int smb5_parse_dt(struct smb5 *chip)
	if (rc < 0)
	if (rc < 0)
		return rc;
		return rc;


	rc = smb5_parse_sdam(chip, node);
	if (rc < 0)
		return rc;

	return 0;
	return 0;
}
}


@@ -828,6 +872,8 @@ static enum power_supply_property smb5_usb_props[] = {
	POWER_SUPPLY_PROP_SKIN_HEALTH,
	POWER_SUPPLY_PROP_SKIN_HEALTH,
	POWER_SUPPLY_PROP_APSD_RERUN,
	POWER_SUPPLY_PROP_APSD_RERUN,
	POWER_SUPPLY_PROP_APSD_TIMEOUT,
	POWER_SUPPLY_PROP_APSD_TIMEOUT,
	POWER_SUPPLY_PROP_CHARGER_STATUS,
	POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
};
};


static int smb5_usb_get_prop(struct power_supply *psy,
static int smb5_usb_get_prop(struct power_supply *psy,
@@ -837,6 +883,7 @@ static int smb5_usb_get_prop(struct power_supply *psy,
	struct smb5 *chip = power_supply_get_drvdata(psy);
	struct smb5 *chip = power_supply_get_drvdata(psy);
	struct smb_charger *chg = &chip->chg;
	struct smb_charger *chg = &chip->chg;
	int rc = 0;
	int rc = 0;
	u8 reg = 0, buff[2] = {0};
	val->intval = 0;
	val->intval = 0;


	switch (psp) {
	switch (psp) {
@@ -977,6 +1024,24 @@ static int smb5_usb_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_APSD_TIMEOUT:
	case POWER_SUPPLY_PROP_APSD_TIMEOUT:
		val->intval = chg->apsd_ext_timeout;
		val->intval = chg->apsd_ext_timeout;
		break;
		break;
	case POWER_SUPPLY_PROP_CHARGER_STATUS:
		val->intval = 0;
		if (chg->sdam_base) {
			rc = smblib_read(chg,
				chg->sdam_base + SDAM_QC_DET_STATUS_REG, &reg);
			if (!rc)
				val->intval = reg;
		}
		break;
	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED:
		val->intval = 0;
		if (chg->sdam_base) {
			rc = smblib_batch_read(chg,
				chg->sdam_base + SDAM_QC_ADC_LSB_REG, buff, 2);
			if (!rc)
				val->intval = (buff[1] << 8 | buff[0]) * 1038;
		}
		break;
	default:
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
		rc = -EINVAL;
@@ -2576,11 +2641,23 @@ static int smb5_init_hw(struct smb5 *chip)
{
{
	struct smb_charger *chg = &chip->chg;
	struct smb_charger *chg = &chip->chg;
	int rc;
	int rc;
	u8 val = 0, mask = 0;
	u8 val = 0, mask = 0, buf[2] = {0};


	if (chip->dt.no_battery)
	if (chip->dt.no_battery)
		chg->fake_capacity = 50;
		chg->fake_capacity = 50;


	if (chg->sdam_base) {
		rc = smblib_write(chg,
			chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0);
		if (rc < 0)
			pr_err("Couldn't clear SDAM QC status rc=%d\n", rc);

		rc = smblib_batch_write(chg,
			chg->sdam_base + SDAM_QC_ADC_LSB_REG, buf, 2);
		if (rc < 0)
			pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc);
	}

	if (chip->dt.batt_profile_fcc_ua < 0)
	if (chip->dt.batt_profile_fcc_ua < 0)
		smblib_get_charge_param(chg, &chg->param.fcc,
		smblib_get_charge_param(chg, &chg->param.fcc,
				&chg->batt_profile_fcc_ua);
				&chg->batt_profile_fcc_ua);
@@ -3673,6 +3750,9 @@ static void smb5_shutdown(struct platform_device *pdev)
	/* disable all interrupts */
	/* disable all interrupts */
	smb5_disable_interrupts(chg);
	smb5_disable_interrupts(chg);


	/* disable the SMB_EN configuration */
	smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT, 0);

	/* configure power role for UFP */
	/* configure power role for UFP */
	if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC)
	if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC)
		smblib_masked_write(chg, TYPE_C_MODE_CFG_REG,
		smblib_masked_write(chg, TYPE_C_MODE_CFG_REG,
+13 −0
Original line number Original line Diff line number Diff line
@@ -6164,6 +6164,7 @@ static void typec_src_removal(struct smb_charger *chg)
	struct smb_irq_data *data;
	struct smb_irq_data *data;
	struct storm_watch *wdata;
	struct storm_watch *wdata;
	int sec_charger;
	int sec_charger;
	u8 val[2] = {0};


	sec_charger = chg->sec_pl_present ? POWER_SUPPLY_CHARGER_SEC_PL :
	sec_charger = chg->sec_pl_present ? POWER_SUPPLY_CHARGER_SEC_PL :
				POWER_SUPPLY_CHARGER_SEC_NONE;
				POWER_SUPPLY_CHARGER_SEC_NONE;
@@ -6254,6 +6255,18 @@ static void typec_src_removal(struct smb_charger *chg)
		smblib_err(chg, "Couldn't write float charger options rc=%d\n",
		smblib_err(chg, "Couldn't write float charger options rc=%d\n",
			rc);
			rc);


	if (chg->sdam_base) {
		rc = smblib_write(chg,
			chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0);
		if (rc < 0)
			pr_err("Couldn't clear SDAM QC status rc=%d\n", rc);

		rc = smblib_batch_write(chg,
			chg->sdam_base + SDAM_QC_ADC_LSB_REG, val, 2);
		if (rc < 0)
			pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc);
	}

	if (!chg->pr_swap_in_progress) {
	if (!chg->pr_swap_in_progress) {
		rc = smblib_usb_pd_adapter_allowance_override(chg, FORCE_NULL);
		rc = smblib_usb_pd_adapter_allowance_override(chg, FORCE_NULL);
		if (rc < 0)
		if (rc < 0)
+1 −0
Original line number Original line Diff line number Diff line
@@ -385,6 +385,7 @@ struct smb_charger {
	struct smb_chg_freq	chg_freq;
	struct smb_chg_freq	chg_freq;
	int			otg_delay_ms;
	int			otg_delay_ms;
	int			weak_chg_icl_ua;
	int			weak_chg_icl_ua;
	u32			sdam_base;
	bool			pd_not_supported;
	bool			pd_not_supported;


	/* locks */
	/* locks */
+5 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@
#define PERPH_SUBTYPE_OFFSET	0x05
#define PERPH_SUBTYPE_OFFSET	0x05
#define SUBTYPE_MASK		GENMASK(7, 0)
#define SUBTYPE_MASK		GENMASK(7, 0)
#define INT_RT_STS_OFFSET	0x10
#define INT_RT_STS_OFFSET	0x10
#define SDAM_TYPE		0x2E


/********************************
/********************************
 *  CHGR Peripheral Registers  *
 *  CHGR Peripheral Registers  *
@@ -549,4 +550,8 @@ enum {
/* SDAM regs */
/* SDAM regs */
#define MISC_PBS_RT_STS_REG			(MISC_PBS_BASE + 0x10)
#define MISC_PBS_RT_STS_REG			(MISC_PBS_BASE + 0x10)
#define PULSE_SKIP_IRQ_BIT			BIT(4)
#define PULSE_SKIP_IRQ_BIT			BIT(4)

#define SDAM_QC_DET_STATUS_REG			0x58
#define SDAM_QC_ADC_LSB_REG			0x54

#endif /* __SMB5_CHARGER_REG_H */
#endif /* __SMB5_CHARGER_REG_H */