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

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

Merge "power: smb138x-charger: Add support of extcon based notifications"

parents 270ba4b6 da912545
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -43,6 +43,13 @@ Charger specific properties:
  Definition: Boolean flag which indicates that the charger should not draw
	      current from any of its input sources (USB, DC).

- qcom,use-extcon
  Usage:      optional
  Value type: <empty>
  Definition: Boolean flag which specify that smb138x will act as main charger
	      to do extcon USB calls. If not defined, other charger driver can
	      act as main charger to do extcon USB calls.

- qcom,fcc-max-ua
  Usage:      optional
  Value type: <u32>
+45 −0
Original line number Diff line number Diff line
@@ -3642,6 +3642,37 @@ static void smblib_force_legacy_icl(struct smb_charger *chg, int pst)
	}
}

static void smblib_notify_extcon_props(struct smb_charger *chg, int id)
{
	union extcon_property_value val;
	union power_supply_propval prop_val;

	smblib_get_prop_typec_cc_orientation(chg, &prop_val);
	val.intval = ((prop_val.intval == 2) ? 1 : 0);
	extcon_set_property(chg->extcon, id,
				EXTCON_PROP_USB_TYPEC_POLARITY, val);

	val.intval = true;
	extcon_set_property(chg->extcon, id,
				EXTCON_PROP_USB_SS, val);
}

static void smblib_notify_device_mode(struct smb_charger *chg, bool enable)
{
	if (enable)
		smblib_notify_extcon_props(chg, EXTCON_USB);

	extcon_set_state_sync(chg->extcon, EXTCON_USB, enable);
}

static void smblib_notify_usb_host(struct smb_charger *chg, bool enable)
{
	if (enable)
		smblib_notify_extcon_props(chg, EXTCON_USB_HOST);

	extcon_set_state_sync(chg->extcon, EXTCON_USB_HOST, enable);
}

#define HVDCP_DET_MS 2500
static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
{
@@ -3664,6 +3695,8 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
		/* if not DCP then no hvdcp timeout happens. Enable pd here */
		vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER,
				false, 0);
		if (chg->use_extcon)
			smblib_notify_device_mode(chg, true);
		break;
	case OCP_CHARGER_BIT:
	case FLOAT_CHARGER_BIT:
@@ -3749,6 +3782,10 @@ static void typec_sink_insertion(struct smb_charger *chg)
	 */
	vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER,
			false, 0);
	if (chg->use_extcon) {
		smblib_notify_usb_host(chg, true);
		chg->otg_present = true;
	}
}

static void typec_sink_removal(struct smb_charger *chg)
@@ -3899,6 +3936,14 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)

	typec_sink_removal(chg);
	smblib_update_usb_type(chg);

	if (chg->use_extcon) {
		if (chg->otg_present)
			smblib_notify_usb_host(chg, false);
		else
			smblib_notify_device_mode(chg, false);
	}
	chg->otg_present = false;
}

static void smblib_handle_typec_insertion(struct smb_charger *chg)
+5 −0
Original line number Diff line number Diff line
@@ -144,6 +144,9 @@ static const unsigned int smblib_extcon_cable[] = {
	EXTCON_NONE,
};

/* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */
static const u32 smblib_extcon_exclusive[] = {0x3, 0};

struct smb_regulator {
	struct regulator_dev	*rdev;
	struct regulator_desc	rdesc;
@@ -331,6 +334,8 @@ struct smb_charger {
	int			usb_icl_change_irq_enabled;
	u32			jeita_status;
	u8			float_cfg;
	bool			use_extcon;
	bool			otg_present;

	/* workaround flag */
	u32			wa_flags;
+51 −8
Original line number Diff line number Diff line
@@ -170,6 +170,9 @@ static int smb138x_parse_dt(struct smb138x *chip)
	chip->dt.suspend_input = of_property_read_bool(node,
				"qcom,suspend-input");

	chg->use_extcon = of_property_read_bool(node,
				"qcom,use-extcon");

	rc = of_property_read_u32(node,
				"qcom,fcc-max-ua", &chip->dt.fcc_ua);
	if (rc < 0)
@@ -1405,55 +1408,95 @@ static int smb138x_master_probe(struct smb138x *chip)
	rc = smb138x_parse_dt(chip);
	if (rc < 0) {
		pr_err("Couldn't parse device tree rc=%d\n", rc);
		return rc;
		goto cleanup;
	}

	rc = smb138x_init_vbus_regulator(chip);
	if (rc < 0) {
		pr_err("Couldn't initialize vbus regulator rc=%d\n",
			rc);
		return rc;
		goto cleanup;
	}

	rc = smb138x_init_vconn_regulator(chip);
	if (rc < 0) {
		pr_err("Couldn't initialize vconn regulator rc=%d\n",
			rc);
		return rc;
		goto cleanup;
	}

	if (chg->use_extcon) {
		/* extcon registration */
		chg->extcon = devm_extcon_dev_allocate(chg->dev,
							smblib_extcon_cable);
		if (IS_ERR(chg->extcon)) {
			rc = PTR_ERR(chg->extcon);
			dev_err(chg->dev, "failed to allocate extcon device rc=%d\n",
					rc);
			goto cleanup;
		}

		chg->extcon->mutually_exclusive = smblib_extcon_exclusive;
		rc = devm_extcon_dev_register(chg->dev, chg->extcon);
		if (rc < 0) {
			dev_err(chg->dev, "failed to register extcon device rc=%d\n",
						rc);
			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 = smb138x_init_usb_psy(chip);
	if (rc < 0) {
		pr_err("Couldn't initialize usb psy rc=%d\n", rc);
		return rc;
		goto cleanup;
	}

	rc = smb138x_init_batt_psy(chip);
	if (rc < 0) {
		pr_err("Couldn't initialize batt psy rc=%d\n", rc);
		return rc;
		goto cleanup;
	}

	rc = smb138x_init_hw(chip);
	if (rc < 0) {
		pr_err("Couldn't initialize hardware rc=%d\n", rc);
		return rc;
		goto cleanup;
	}

	rc = smb138x_determine_initial_status(chip);
	if (rc < 0) {
		pr_err("Couldn't determine initial status rc=%d\n",
			rc);
		return rc;
		goto cleanup;
	}

	rc = smb138x_request_interrupts(chip);
	if (rc < 0) {
		pr_err("Couldn't request interrupts rc=%d\n", rc);
		return rc;
		goto cleanup;
	}

	return rc;

cleanup:
	smblib_deinit(chg);
	return rc;
}

static int smb138x_slave_probe(struct smb138x *chip)