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

Commit 26d4132e authored by Abhijeet Dharmapurikar's avatar Abhijeet Dharmapurikar
Browse files

power: qpnp-smbcharger: add support to skip USB notifications



Some hardware configurations allow the USB driver to detect presence
and type without charger's APSD. This is true especially when the external
muxes are used to multiplex an USB port and a docking station on the usbin
input line.

The USB port when active, ends up notifying the USB driver via a gpio.
When docking station is active, USB side need not know about it.

Note that this change also removes the null checks for usb_psy. It is
initialized at probe and probe's success is dependent on proper usb_psy
detection and initialization.

Change-Id: I7e300ce19d82861f34ccf37545f3317221f727a9
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
parent 3a3a3988
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -258,6 +258,9 @@ Optional Properties:
- qcom,chg-led-support		A bool property to support the charger led feature.
- qcom,chg-led-sw-controls		A bool property to allow the software to control
					the charger led without a valid charger.
- qcom,skip-usb-notification	A boolean property to be used when usb gets present
				and type from other means. Especially true on
				liquid hardware, where usb presence is detected based on GPIO.

Example:
	qcom,qpnp-smbcharger {
+51 −38
Original line number Diff line number Diff line
@@ -241,6 +241,7 @@ struct smbchg_chip {
	struct completion		usbin_uv_raised;
	int				pulse_cnt;
	struct led_classdev		led_cdev;
	bool				skip_usb_notification;
};

enum qpnp_schg {
@@ -3833,10 +3834,12 @@ static void smbchg_hvdcp_det_work(struct work_struct *work)
				struct smbchg_chip,
				hvdcp_det_work.work);
	if (is_hvdcp_present(chip)) {
		if (!chip->skip_usb_notification) {
			pr_smb(PR_MISC, "setting usb psy type = %d\n",
					POWER_SUPPLY_TYPE_USB_HVDCP);
			power_supply_set_supply_type(chip->usb_psy,
					POWER_SUPPLY_TYPE_USB_HVDCP);
		}
		if (chip->psy_registered)
			power_supply_changed(&chip->batt_psy);
		smbchg_aicl_deglitch_wa_check(chip);
@@ -3926,7 +3929,7 @@ static void handle_usb_removal(struct smbchg_chip *chip)
	/* Clear the OV detected status set before */
	if (chip->usb_ov_det)
		chip->usb_ov_det = false;
	if (chip->usb_psy) {
	if (!chip->skip_usb_notification) {
		pr_smb(PR_MISC, "setting usb psy type = %d\n",
				POWER_SUPPLY_TYPE_UNKNOWN);
		power_supply_set_supply_type(chip->usb_psy,
@@ -3934,16 +3937,17 @@ static void handle_usb_removal(struct smbchg_chip *chip)
		pr_smb(PR_MISC, "setting usb psy present = %d\n",
				chip->usb_present);
		power_supply_set_present(chip->usb_psy, chip->usb_present);
	}
	set_usb_psy_dp_dm(chip, POWER_SUPPLY_DP_DM_DPR_DMR);
	schedule_work(&chip->usb_set_online_work);
	pr_smb(PR_MISC, "setting usb psy health UNKNOWN\n");
	rc = power_supply_set_health_state(chip->usb_psy,
			POWER_SUPPLY_HEALTH_UNKNOWN);
		if (rc)
	if (rc < 0)
		pr_smb(PR_STATUS,
			"usb psy does not allow updating prop %d rc = %d\n",
			POWER_SUPPLY_HEALTH_UNKNOWN, rc);
	}

	if (parallel_psy && chip->parallel_charger_detected)
		power_supply_set_present(parallel_psy, false);
	if (chip->parallel.avail && chip->aicl_done_irq
@@ -4005,13 +4009,15 @@ static void handle_usb_insertion(struct smbchg_chip *chip)
		"inserted type = %d (%s)", usb_supply_type, usb_type_name);

	smbchg_aicl_deglitch_wa_check(chip);
	if (chip->usb_psy) {
	if (!chip->skip_usb_notification) {
		pr_smb(PR_MISC, "setting usb psy type = %d\n",
				usb_supply_type);
		power_supply_set_supply_type(chip->usb_psy, usb_supply_type);
		pr_smb(PR_MISC, "setting usb psy present = %d\n",
				chip->usb_present);
		power_supply_set_present(chip->usb_psy, chip->usb_present);
	}

	/* Notify the USB psy if OV condition is not present */
	if (!chip->usb_ov_det) {
		/*
@@ -4026,13 +4032,12 @@ static void handle_usb_insertion(struct smbchg_chip *chip)
				chip->very_weak_charger
				? POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
				: POWER_SUPPLY_HEALTH_GOOD);
			if (rc)
		if (rc < 0)
			pr_smb(PR_STATUS,
				"usb psy does not allow updating prop %d rc = %d\n",
				POWER_SUPPLY_HEALTH_GOOD, rc);
	}
	schedule_work(&chip->usb_set_online_work);
	}

	if (usb_supply_type == POWER_SUPPLY_TYPE_USB_DCP)
		schedule_delayed_work(&chip->hvdcp_det_work,
@@ -4593,8 +4598,10 @@ static int smbchg_hvdcp3_confirmed(struct smbchg_chip *chip)

	pr_smb(PR_MISC, "setting usb psy type = %d\n",
				POWER_SUPPLY_TYPE_USB_HVDCP_3);
	if (!chip->skip_usb_notification) {
		power_supply_set_supply_type(chip->usb_psy,
				POWER_SUPPLY_TYPE_USB_HVDCP_3);
	}
	return 0;
}

@@ -6217,6 +6224,9 @@ static int smb_parse_dt(struct smbchg_chip *chip)
		}
	}

	chip->skip_usb_notification
		= of_property_read_bool(node,
				"qcom,skip-usb-notification");
	return 0;
}

@@ -6736,8 +6746,11 @@ static int smbchg_probe(struct spmi_device *spmi)
		goto unregister_led_class;
	}

	pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present);
	if (!chip->skip_usb_notification) {
		pr_smb(PR_MISC, "setting usb psy present = %d\n",
			chip->usb_present);
		power_supply_set_present(chip->usb_psy, chip->usb_present);
	}

	dump_regs(chip);
	create_debugfs_entries(chip);