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

Commit 1def2a4a authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: smb5: Add extcon capability to report orientation and speed"

parents c7a63c12 24ecafa1
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -280,6 +280,12 @@ Charger specific properties:
  Value type: bool
  Definition: Boolean flag which when present disables USB-PD operation.

- qcom,lpd-disable
  Usage:      optional
  Value type: bool
  Definition: Boolean flag which when present disables liquid presence
		detection.

- qcom,hw-die-temp-mitigation
  Usage:      optional
  Value type: bool
+211 −148
Original line number Diff line number Diff line
@@ -340,6 +340,9 @@ static int smb5_chg_config_init(struct smb5 *chip)
		chg->name = "pmi632_charger";
		/* PMI632 does not support PD */
		chg->pd_not_supported = true;
		chg->lpd_disabled = true;
		if (pmic_rev_id->rev4 >= 2)
			chg->uusb_moisture_protection_enabled = true;
		chg->hw_max_icl_ua =
			(chip->dt.usb_icl_ua > 0) ? chip->dt.usb_icl_ua
						: PMI632_MAX_ICL_UA;
@@ -436,6 +439,8 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node)
	chg->pd_not_supported = of_property_read_bool(node,
				"qcom,usb-pd-disable");

	chg->lpd_disabled = of_property_read_bool(node, "qcom,lpd-disable");

	rc = of_property_read_u32(node, "qcom,wd-bark-time-secs",
					&chip->dt.wd_bark_time);
	if (rc < 0 || chip->dt.wd_bark_time < MIN_WD_BARK_TIME)
@@ -1831,10 +1836,10 @@ static int smb5_configure_typec(struct smb_charger *chg)
		return rc;
	}

	val = chg->lpd_disabled ? 0 : TYPEC_WATER_DETECTION_INT_EN_BIT;
	/* Use simple write to enable only required interrupts */
	rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG,
				TYPEC_SRC_BATT_HPWR_INT_EN_BIT |
				TYPEC_WATER_DETECTION_INT_EN_BIT);
				TYPEC_SRC_BATT_HPWR_INT_EN_BIT | val);
	if (rc < 0) {
		dev_err(chg->dev,
			"Couldn't configure Type-C interrupts rc=%d\n", rc);
@@ -1926,7 +1931,9 @@ static int smb5_configure_micro_usb(struct smb_charger *chg)
		}

		/* Disable periodic monitoring of CC_ID pin */
		rc = smblib_write(chg, TYPEC_U_USB_WATER_PROTECTION_CFG_REG, 0);
		rc = smblib_write(chg, ((chg->smb_version == PMI632_SUBTYPE) ?
			PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG :
			TYPEC_U_USB_WATER_PROTECTION_CFG_REG), 0);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't disable periodic monitoring of CC_ID rc=%d\n",
				rc);
@@ -2090,12 +2097,189 @@ static int smb5_init_dc_peripheral(struct smb_charger *chg)
	return rc;
}

static int smb5_init_hw(struct smb5 *chip)
static int smb5_configure_recharging(struct smb5 *chip)
{
	int rc = 0;
	struct smb_charger *chg = &chip->chg;
	union power_supply_propval pval;
	/* Configure VBATT-based or automatic recharging */

	rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK,
				(chip->dt.auto_recharge_vbat_mv != -EINVAL) ?
				VBAT_BASED_RECHG_BIT : 0);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure VBAT-rechg CHG_CFG2_REG rc=%d\n",
			rc);
		return rc;
	}

	/* program the auto-recharge VBAT threshold */
	if (chip->dt.auto_recharge_vbat_mv != -EINVAL) {
		u32 temp = VBAT_TO_VRAW_ADC(chip->dt.auto_recharge_vbat_mv);

		temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8);
		rc = smblib_batch_write(chg,
			CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG, (u8 *)&temp, 2);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure ADC_RECHARGE_THRESHOLD REG rc=%d\n",
				rc);
			return rc;
		}
		/* Program the sample count for VBAT based recharge to 3 */
		rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG,
					NO_OF_SAMPLE_FOR_RCHG,
					2 << NO_OF_SAMPLE_FOR_RCHG_SHIFT);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n",
				rc);
			return rc;
		}
	}

	rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK,
				(chip->dt.auto_recharge_soc != -EINVAL) ?
				SOC_BASED_RECHG_BIT : VBAT_BASED_RECHG_BIT);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure SOC-rechg CHG_CFG2_REG rc=%d\n",
			rc);
		return rc;
	}

	/* program the auto-recharge threshold */
	if (chip->dt.auto_recharge_soc != -EINVAL) {
		pval.intval = chip->dt.auto_recharge_soc;
		rc = smblib_set_prop_rechg_soc_thresh(chg, &pval);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n",
					rc);
			return rc;
		}

		/* Program the sample count for SOC based recharge to 1 */
		rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG,
						NO_OF_SAMPLE_FOR_RCHG, 0);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n",
				rc);
			return rc;
		}
	}

	return 0;
}

static int smb5_configure_float_charger(struct smb5 *chip)
{
	int rc = 0;
	struct smb_charger *chg = &chip->chg;

	/* configure float charger options */
	switch (chip->dt.float_option) {
	case FLOAT_DCP:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, 0);
		break;
	case FLOAT_SDP:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, FORCE_FLOAT_SDP_CFG_BIT);
		break;
	case DISABLE_CHARGING:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, FLOAT_DIS_CHGING_CFG_BIT);
		break;
	case SUSPEND_INPUT:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, SUSPEND_FLOAT_CFG_BIT);
		break;
	default:
		rc = 0;
		break;
	}

	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure float charger options rc=%d\n",
			rc);
		return rc;
	}

	rc = smblib_read(chg, USBIN_OPTIONS_2_CFG_REG, &chg->float_cfg);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't read float charger options rc=%d\n",
			rc);
		return rc;
	}

	return 0;
}

static int smb5_init_connector_type(struct smb_charger *chg)
{
	int rc, type = 0;
	u8 val = 0;

	/*
	 * PMI632 can have the connector type defined by a dedicated register
	 * PMI632_TYPEC_MICRO_USB_MODE_REG or by a common TYPEC_U_USB_CFG_REG.
	 */
	if (chg->smb_version == PMI632_SUBTYPE) {
		rc = smblib_read(chg, PMI632_TYPEC_MICRO_USB_MODE_REG, &val);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't read USB mode rc=%d\n", rc);
			return rc;
		}
		type = !!(val & MICRO_USB_MODE_ONLY_BIT);
	}

	/*
	 * If PMI632_TYPEC_MICRO_USB_MODE_REG is not set and for all non-PMI632
	 * check the connector type using TYPEC_U_USB_CFG_REG.
	 */
	if (!type) {
		rc = smblib_read(chg, TYPEC_U_USB_CFG_REG, &val);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't read U_USB config rc=%d\n",
					rc);
			return rc;
		}

		type = !!(val & EN_MICRO_USB_MODE_BIT);
	}

	pr_debug("Connector type=%s\n", type ? "Micro USB" : "TypeC");

	if (type) {
		chg->connector_type = POWER_SUPPLY_CONNECTOR_MICRO_USB;
		rc = smb5_configure_micro_usb(chg);
	} else {
		chg->connector_type = POWER_SUPPLY_CONNECTOR_TYPEC;
		rc = smb5_configure_typec(chg);
	}
	if (rc < 0) {
		dev_err(chg->dev,
			"Couldn't configure TypeC/micro-USB mode rc=%d\n", rc);
		return rc;
	}

	/*
	 * PMI632 based hw init:
	 * - Rerun APSD to ensure proper charger detection if device
	 *   boots with charger connected.
	 * - Initialize flash module for PMI632
	 */
	if (chg->smb_version == PMI632_SUBTYPE) {
		schgm_flash_init(chg);
		smblib_rerun_apsd_if_required(chg);
	}

	return 0;

}

static int smb5_init_hw(struct smb5 *chip)
{
	struct smb_charger *chg = &chip->chg;
	int rc;
	u8 val = 0, mask = 0;
	union power_supply_propval pval;

	if (chip->dt.no_battery)
		chg->fake_capacity = 50;
@@ -2170,60 +2354,13 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;
	}

	/*
	 * PMI632 can have the connector type defined by a dedicated register
	 * TYPEC_MICRO_USB_MODE_REG or by a common TYPEC_U_USB_CFG_REG.
	 */
	if (chg->smb_version == PMI632_SUBTYPE) {
		rc = smblib_read(chg, TYPEC_MICRO_USB_MODE_REG, &val);
	rc = smb5_init_connector_type(chg);
	if (rc < 0) {
			dev_err(chg->dev, "Couldn't read USB mode rc=%d\n", rc);
			return rc;
		}
		type = !!(val & MICRO_USB_MODE_ONLY_BIT);
	}

	/*
	 * If TYPEC_MICRO_USB_MODE_REG is not set and for all non-PMI632
	 * check the connector type using TYPEC_U_USB_CFG_REG.
	 */
	if (!type) {
		rc = smblib_read(chg, TYPEC_U_USB_CFG_REG, &val);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't read U_USB config rc=%d\n",
		dev_err(chg->dev, "Couldn't configure connector type rc=%d\n",
				rc);
		return rc;
	}

		type = !!(val & EN_MICRO_USB_MODE_BIT);
	}

	pr_debug("Connector type=%s\n", type ? "Micro USB" : "TypeC");

	if (type) {
		chg->connector_type = POWER_SUPPLY_CONNECTOR_MICRO_USB;
		rc = smb5_configure_micro_usb(chg);
	} else {
		chg->connector_type = POWER_SUPPLY_CONNECTOR_TYPEC;
		rc = smb5_configure_typec(chg);
	}
	if (rc < 0) {
		dev_err(chg->dev,
			"Couldn't configure TypeC/micro-USB mode rc=%d\n", rc);
		return rc;
	}

	/*
	 * PMI632 based hw init:
	 * - Rerun APSD to ensure proper charger detection if device
	 *   boots with charger connected.
	 * - Initialize flash module for PMI632
	 */
	if (chg->smb_version == PMI632_SUBTYPE) {
		schgm_flash_init(chg);
		smblib_rerun_apsd_if_required(chg);
	}

	/* Use ICL results from HW */
	rc = smblib_icl_override(chg, HW_AUTO_MODE);
	if (rc < 0) {
@@ -2337,41 +2474,9 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;
	}

	/* configure float charger options */
	switch (chip->dt.float_option) {
	case FLOAT_DCP:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, 0);
		break;
	case FLOAT_SDP:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, FORCE_FLOAT_SDP_CFG_BIT);
		break;
	case DISABLE_CHARGING:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, FLOAT_DIS_CHGING_CFG_BIT);
		break;
	case SUSPEND_INPUT:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, SUSPEND_FLOAT_CFG_BIT);
		break;
	default:
		rc = 0;
		break;
	}

	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure float charger options rc=%d\n",
			rc);
		return rc;
	}

	rc = smblib_read(chg, USBIN_OPTIONS_2_CFG_REG, &chg->float_cfg);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't read float charger options rc=%d\n",
			rc);
	rc = smb5_configure_float_charger(chip);
	if (rc < 0)
		return rc;
	}

	switch (chip->dt.chg_inhibit_thr_mv) {
	case 50:
@@ -2415,66 +2520,9 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;
	}

	rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK,
				(chip->dt.auto_recharge_vbat_mv != -EINVAL) ?
				VBAT_BASED_RECHG_BIT : 0);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure VBAT-rechg CHG_CFG2_REG rc=%d\n",
			rc);
		return rc;
	}

	/* program the auto-recharge VBAT threshold */
	if (chip->dt.auto_recharge_vbat_mv != -EINVAL) {
		u32 temp = VBAT_TO_VRAW_ADC(chip->dt.auto_recharge_vbat_mv);

		temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8);
		rc = smblib_batch_write(chg,
			CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG, (u8 *)&temp, 2);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure ADC_RECHARGE_THRESHOLD REG rc=%d\n",
				rc);
			return rc;
		}
		/* Program the sample count for VBAT based recharge to 3 */
		rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG,
					NO_OF_SAMPLE_FOR_RCHG,
					2 << NO_OF_SAMPLE_FOR_RCHG_SHIFT);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n",
				rc);
			return rc;
		}
	}

	rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK,
				(chip->dt.auto_recharge_soc != -EINVAL) ?
				SOC_BASED_RECHG_BIT : VBAT_BASED_RECHG_BIT);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure SOC-rechg CHG_CFG2_REG rc=%d\n",
			rc);
		return rc;
	}

	/* program the auto-recharge threshold */
	if (chip->dt.auto_recharge_soc != -EINVAL) {
		pval.intval = chip->dt.auto_recharge_soc;
		rc = smblib_set_prop_rechg_soc_thresh(chg, &pval);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n",
					rc);
			return rc;
		}

		/* Program the sample count for SOC based recharge to 1 */
		rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG,
						NO_OF_SAMPLE_FOR_RCHG, 0);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n",
				rc);
	rc = smb5_configure_recharging(chip);
	if (rc < 0)
		return rc;
		}
	}

	rc = smblib_disable_hw_jeita(chg, true);
	if (rc < 0) {
@@ -3129,6 +3177,21 @@ static int smb5_probe(struct platform_device *pdev)
		goto cleanup;
	}

	/* Support reporting polarity and speed via properties */
	rc = extcon_set_property_capability(chg->extcon,
			EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY);
	rc |= extcon_set_property_capability(chg->extcon,
			EXTCON_USB, EXTCON_PROP_USB_SS);
	rc |= extcon_set_property_capability(chg->extcon,
			EXTCON_USB_HOST, EXTCON_PROP_USB_TYPEC_POLARITY);
	rc |= extcon_set_property_capability(chg->extcon,
			EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
	if (rc < 0) {
		dev_err(chg->dev,
			"failed to configure extcon capabilities\n");
		goto cleanup;
	}

	rc = smb5_init_hw(chip);
	if (rc < 0) {
		pr_err("Couldn't initialize hardware rc=%d\n", rc);
+14 −1
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@
#define BATT_GT_PRE_TO_FAST_BIT			BIT(4)
#define ENABLE_CHARGING_BIT			BIT(3)

#define CHGR_CHARGING_ENABLE_CMD_REG		(CHGR_BASE + 0x42)
#define CHARGING_ENABLE_CMD_BIT			BIT(0)

#define CHGR_CFG2_REG				(CHGR_BASE + 0x51)
#define CHG_EN_SRC_BIT				BIT(7)
#define CHG_EN_POLARITY_BIT			BIT(6)
@@ -1032,7 +1035,17 @@ static int smb1355_init_hw(struct smb1355 *chip)
		return rc;
	}

	/* disable parallel charging path */
	/*
	 * Disable command based SMB1355 enablement and disable parallel
	 * charging path by switching to command based mode.
	 */
	rc = smb1355_masked_write(chip, CHGR_CHARGING_ENABLE_CMD_REG,
				CHARGING_ENABLE_CMD_BIT, 0);
	if (rc < 0) {
		pr_err("Coudln't configure command bit, rc=%d\n", rc);
		return rc;
	}

	rc = smb1355_set_parallel_charging(chip, true);
	if (rc < 0) {
		pr_err("Couldn't disable parallel path rc=%d\n", rc);
+52 −34
Original line number Diff line number Diff line
@@ -124,7 +124,6 @@ struct smb1390 {
	struct votable		*ilim_votable;
	struct votable		*fcc_votable;
	struct votable		*fv_votable;
	struct votable		*cp_awake_votable;

	/* power supplies */
	struct power_supply	*usb_psy;
@@ -138,7 +137,9 @@ struct smb1390 {
	struct smb1390_iio	iio;
	int			irq_status;
	int			taper_entry_fv;
	bool			switcher_disabled;
	bool			switcher_enabled;
	int			die_temp;
	bool			suspended;
};

struct smb_irq {
@@ -276,8 +277,8 @@ static irqreturn_t default_irq_handler(int irq, void *data)

	rc = smb1390_get_cp_en_status(chip, SWITCHER_EN, &enable);
	if (!rc) {
		if (chip->switcher_disabled == enable) {
			chip->switcher_disabled = !chip->switcher_disabled;
		if (chip->switcher_enabled != enable) {
			chip->switcher_enabled = enable;
			if (chip->fcc_votable)
				rerun_election(chip->fcc_votable);
		}
@@ -424,7 +425,7 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data,
	struct smb1390 *chip = data;
	int rc = 0;

	if (!is_psy_voter_available(chip))
	if (!is_psy_voter_available(chip) || chip->suspended)
		return -EAGAIN;

	if (disable) {
@@ -432,10 +433,7 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data,
				   CMD_EN_SWITCHER_BIT, 0);
		if (rc < 0)
			return rc;

		vote(chip->cp_awake_votable, CP_VOTER, false, 0);
	} else {
		vote(chip->cp_awake_votable, CP_VOTER, true, 0);
		rc = smb1390_masked_write(chip, CORE_CONTROL1_REG,
				   CMD_EN_SWITCHER_BIT, CMD_EN_SWITCHER_BIT);
		if (rc < 0)
@@ -454,7 +452,7 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
	struct smb1390 *chip = data;
	int rc = 0;

	if (!is_psy_voter_available(chip))
	if (!is_psy_voter_available(chip) || chip->suspended)
		return -EAGAIN;

	/* ILIM should always have at least one active vote */
@@ -483,20 +481,6 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
	return rc;
}

static int smb1390_awake_vote_cb(struct votable *votable, void *data,
				int awake, const char *client)
{
	struct smb1390 *chip = data;

	if (awake)
		__pm_stay_awake(chip->cp_ws);
	else
		__pm_relax(chip->cp_ws);

	pr_debug("client: %s awake: %d\n", client, awake);
	return 0;
}

static int smb1390_notifier_cb(struct notifier_block *nb,
			       unsigned long event, void *data)
{
@@ -705,12 +689,26 @@ static int smb1390_get_prop(struct power_supply *psy,
				!get_effective_result(chip->disable_votable);
		break;
	case POWER_SUPPLY_PROP_CP_SWITCHER_EN:
		rc = smb1390_get_cp_en_status(chip, SWITCHER_EN, &enable);
		if (chip->suspended) {
			val->intval = chip->switcher_enabled;
		} else {
			rc = smb1390_get_cp_en_status(chip, SWITCHER_EN,
					&enable);
			if (!rc)
				val->intval = enable;
		}
		break;
	case POWER_SUPPLY_PROP_CP_DIE_TEMP:
		if (chip->suspended) {
			if (chip->die_temp != -ENODATA)
				val->intval = chip->die_temp;
			else
				rc = -ENODATA;
		} else {
			rc = smb1390_get_die_temp(chip, val);
			if (rc >= 0)
				chip->die_temp = val->intval;
		}
		break;
	case POWER_SUPPLY_PROP_CP_ISNS:
		rc = smb1390_get_isns(chip, val);
@@ -844,11 +842,6 @@ static void smb1390_release_channels(struct smb1390 *chip)

static int smb1390_create_votables(struct smb1390 *chip)
{
	chip->cp_awake_votable = create_votable("CP_AWAKE", VOTE_SET_ANY,
			smb1390_awake_vote_cb, chip);
	if (IS_ERR(chip->cp_awake_votable))
		return PTR_ERR(chip->cp_awake_votable);

	chip->disable_votable = create_votable("CP_DISABLE",
			VOTE_SET_ANY, smb1390_disable_vote_cb, chip);
	if (IS_ERR(chip->disable_votable))
@@ -880,7 +873,6 @@ static void smb1390_destroy_votables(struct smb1390 *chip)
{
	destroy_votable(chip->disable_votable);
	destroy_votable(chip->ilim_votable);
	destroy_votable(chip->cp_awake_votable);
}

static int smb1390_init_hw(struct smb1390 *chip)
@@ -989,7 +981,8 @@ static int smb1390_probe(struct platform_device *pdev)
	chip->dev = &pdev->dev;
	spin_lock_init(&chip->status_change_lock);
	mutex_init(&chip->die_chan_lock);
	chip->switcher_disabled = true;
	chip->die_temp = -ENODATA;
	platform_set_drvdata(pdev, chip);

	chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
	if (!chip->regmap) {
@@ -1071,6 +1064,30 @@ static int smb1390_remove(struct platform_device *pdev)
	return 0;
}

static int smb1390_suspend(struct device *dev)
{
	struct smb1390 *chip = dev_get_drvdata(dev);

	chip->suspended = true;
	return 0;
}

static int smb1390_resume(struct device *dev)
{
	struct smb1390 *chip = dev_get_drvdata(dev);

	chip->suspended = false;
	rerun_election(chip->ilim_votable);
	rerun_election(chip->disable_votable);

	return 0;
}

static const struct dev_pm_ops smb1390_pm_ops = {
	.suspend	= smb1390_suspend,
	.resume		= smb1390_resume,
};

static const struct of_device_id match_table[] = {
	{ .compatible = "qcom,smb1390-charger-psy", },
	{ },
@@ -1079,6 +1096,7 @@ static const struct of_device_id match_table[] = {
static struct platform_driver smb1390_driver = {
	.driver	= {
		.name		= "qcom,smb1390-charger-psy",
		.pm		= &smb1390_pm_ops,
		.of_match_table	= match_table,
	},
	.probe	= smb1390_probe,
+66 −30
Original line number Diff line number Diff line
@@ -1423,7 +1423,9 @@ static int smblib_set_moisture_protection(struct smb_charger *chg,

		/* Set 1% duty cycle on ID detection */
		rc = smblib_masked_write(chg,
					TYPEC_U_USB_WATER_PROTECTION_CFG_REG,
				((chg->smb_version == PMI632_SUBTYPE) ?
				PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG :
				TYPEC_U_USB_WATER_PROTECTION_CFG_REG),
				EN_MICRO_USB_WATER_PROTECTION_BIT |
				MICRO_USB_DETECTION_ON_TIME_CFG_MASK |
				MICRO_USB_DETECTION_PERIOD_CFG_MASK,
@@ -1454,7 +1456,9 @@ static int smblib_set_moisture_protection(struct smb_charger *chg,
		}

		/* Disable periodic monitoring of CC_ID pin */
		rc = smblib_write(chg, TYPEC_U_USB_WATER_PROTECTION_CFG_REG, 0);
		rc = smblib_write(chg, ((chg->smb_version == PMI632_SUBTYPE) ?
				PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG :
				TYPEC_U_USB_WATER_PROTECTION_CFG_REG), 0);
		if (rc < 0) {
			smblib_err(chg, "Couldn't disable 1 percent CC_ID duty cycle rc=%d\n",
				rc);
@@ -2730,6 +2734,11 @@ int smblib_get_prop_dc_present(struct smb_charger *chg,
	int rc;
	u8 stat;

	if (chg->smb_version == PMI632_SUBTYPE) {
		val->intval = 0;
		return 0;
	}

	rc = smblib_read(chg, DCIN_BASE + INT_RT_STS_OFFSET, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read DCIN_RT_STS rc=%d\n", rc);
@@ -2746,6 +2755,11 @@ int smblib_get_prop_dc_online(struct smb_charger *chg,
	int rc = 0;
	u8 stat;

	if (chg->smb_version == PMI632_SUBTYPE) {
		val->intval = 0;
		return 0;
	}

	if (get_client_vote(chg->dc_suspend_votable, USER_VOTER)) {
		val->intval = false;
		return rc;
@@ -4897,6 +4911,9 @@ static bool smblib_src_lpd(struct smb_charger *chg)
	u8 stat;
	int rc;

	if (chg->lpd_disabled)
		return false;

	rc = smblib_read(chg, TYPE_C_SRC_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read TYPE_C_SRC_STATUS_REG rc=%d\n",
@@ -5139,12 +5156,35 @@ static void smblib_handle_rp_change(struct smb_charger *chg, int typec_mode)
						chg->typec_mode, typec_mode);
}

static void smblib_lpd_launch_ra_open_work(struct smb_charger *chg)
{
	u8 stat;
	int rc;

	if (chg->lpd_disabled)
		return;

	rc = smblib_read(chg, TYPE_C_MISC_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read TYPE_C_MISC_STATUS_REG rc=%d\n",
			rc);
		return;
	}

	if (!(stat & TYPEC_TCCDEBOUNCE_DONE_STATUS_BIT)
			&& chg->lpd_stage == LPD_STAGE_NONE) {
		chg->lpd_stage = LPD_STAGE_FLOAT;
		cancel_delayed_work_sync(&chg->lpd_ra_open_work);
		vote(chg->awake_votable, LPD_VOTER, true, 0);
		schedule_delayed_work(&chg->lpd_ra_open_work,
						msecs_to_jiffies(300));
	}
}

irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data)
{
	struct smb_irq_data *irq_data = data;
	struct smb_charger *chg = irq_data->parent_data;
	u8 stat;
	int rc;

	smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name);

@@ -5176,21 +5216,7 @@ irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data)
	if (chg->pr_swap_in_progress || chg->pd_hard_reset)
		goto out;

	rc = smblib_read(chg, TYPE_C_MISC_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read TYPE_C_MISC_STATUS_REG rc=%d\n",
			rc);
		goto out;
	}

	if (!(stat & TYPEC_TCCDEBOUNCE_DONE_STATUS_BIT)
			&& chg->lpd_stage == LPD_STAGE_NONE) {
		chg->lpd_stage = LPD_STAGE_FLOAT;
		cancel_delayed_work_sync(&chg->lpd_ra_open_work);
		vote(chg->awake_votable, LPD_VOTER, true, 0);
		schedule_delayed_work(&chg->lpd_ra_open_work,
						msecs_to_jiffies(300));
	}
	smblib_lpd_launch_ra_open_work(chg);

	if (chg->usb_psy)
		power_supply_changed(chg->usb_psy);
@@ -5225,6 +5251,16 @@ irqreturn_t typec_state_change_irq_handler(int irq, void *data)
	return IRQ_HANDLED;
}

static void smblib_lpd_clear_ra_open_work(struct smb_charger *chg)
{
	if (chg->lpd_disabled)
		return;

	cancel_delayed_work_sync(&chg->lpd_detach_work);
	chg->lpd_stage = LPD_STAGE_FLOAT_CANCEL;
	cancel_delayed_work_sync(&chg->lpd_ra_open_work);
	vote(chg->awake_votable, LPD_VOTER, false, 0);
}

irqreturn_t typec_attach_detach_irq_handler(int irq, void *data)
{
@@ -5243,10 +5279,8 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data)
	}

	if (stat & TYPEC_ATTACH_DETACH_STATE_BIT) {
		cancel_delayed_work_sync(&chg->lpd_detach_work);
		chg->lpd_stage = LPD_STAGE_FLOAT_CANCEL;
		cancel_delayed_work_sync(&chg->lpd_ra_open_work);
		vote(chg->awake_votable, LPD_VOTER, false, 0);

		smblib_lpd_clear_ra_open_work(chg);

		rc = smblib_read(chg, TYPE_C_MISC_STATUS_REG, &stat);
		if (rc < 0) {
@@ -5782,7 +5816,9 @@ static void smblib_moisture_protection_work(struct work_struct *work)
	 * Disable 1% duty cycle on CC_ID pin and enable uUSB factory mode
	 * detection to track any change on RID, as interrupts are disable.
	 */
	rc = smblib_write(chg, TYPEC_U_USB_WATER_PROTECTION_CFG_REG, 0);
	rc = smblib_write(chg, ((chg->smb_version == PMI632_SUBTYPE) ?
			PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG :
			TYPEC_U_USB_WATER_PROTECTION_CFG_REG), 0);
	if (rc < 0) {
		smblib_err(chg, "Couldn't disable periodic monitoring of CC_ID rc=%d\n",
			rc);
Loading