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

Commit 7e28f4fb authored by Ashish Chavan's avatar Ashish Chavan
Browse files

power: qpnp-smb5: Add support to rerun APSD and report APSD ext timeout



Add support to rerun charger power source detection through APSD_RERUN
and expose the software extented timer timeout for HVDCP3 through
APSD_TIMEOUT property.

Change-Id: I99216769633d7e2e6291dfb3691a10a59f48af35
Signed-off-by: default avatarAshish Chavan <ashichav@codeaurora.org>
parent 9228d604
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
 */

#include <linux/debugfs.h>
@@ -820,6 +820,8 @@ static enum power_supply_property smb5_usb_props[] = {
	POWER_SUPPLY_PROP_VOLTAGE_VPH,
	POWER_SUPPLY_PROP_THERM_ICL_LIMIT,
	POWER_SUPPLY_PROP_SKIN_HEALTH,
	POWER_SUPPLY_PROP_APSD_RERUN,
	POWER_SUPPLY_PROP_APSD_TIMEOUT,
};

static int smb5_usb_get_prop(struct power_supply *psy,
@@ -963,6 +965,12 @@ static int smb5_usb_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_SKIN_HEALTH:
		val->intval = smblib_get_skin_temp_status(chg);
		break;
	case POWER_SUPPLY_PROP_APSD_RERUN:
		val->intval = 0;
		break;
	case POWER_SUPPLY_PROP_APSD_TIMEOUT:
		val->intval = chg->apsd_ext_timeout;
		break;
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
@@ -1052,6 +1060,11 @@ static int smb5_usb_set_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_ADAPTER_CC_MODE:
		chg->adapter_cc_mode = val->intval;
		break;
	case POWER_SUPPLY_PROP_APSD_RERUN:
		del_timer_sync(&chg->apsd_timer);
		chg->apsd_ext_timeout = false;
		smblib_rerun_apsd(chg);
		break;
	default:
		pr_err("set prop %d is not supported\n", psp);
		rc = -EINVAL;
@@ -1070,6 +1083,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy,
	case POWER_SUPPLY_PROP_THERM_ICL_LIMIT:
	case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT:
	case POWER_SUPPLY_PROP_ADAPTER_CC_MODE:
	case POWER_SUPPLY_PROP_APSD_RERUN:
		return 1;
	default:
		break;
+44 −8
Original line number Diff line number Diff line
@@ -1033,7 +1033,7 @@ static int smblib_request_dpdm(struct smb_charger *chg, bool enable)
	return rc;
}

static void smblib_rerun_apsd(struct smb_charger *chg)
void smblib_rerun_apsd(struct smb_charger *chg)
{
	int rc;

@@ -1208,6 +1208,9 @@ static void smblib_uusb_removal(struct smb_charger *chg)
	chg->uusb_apsd_rerun_done = false;
	chg->chg_param.forced_main_fcc = 0;

	del_timer_sync(&chg->apsd_timer);
	chg->apsd_ext_timeout = false;

	/* write back the default FLOAT charger configuration */
	rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				(u8)FLOAT_OPTIONS_MASK, chg->float_cfg);
@@ -5444,6 +5447,7 @@ static void smblib_handle_sdp_enumeration_done(struct smb_charger *chg,
		   rising ? "rising" : "falling");
}

#define APSD_EXTENDED_TIMEOUT_MS	400
/* triggers when HVDCP 3.0 authentication has finished */
static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg,
					      bool rising)
@@ -5460,13 +5464,29 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg,
	/* the APSD done handler will set the USB supply type */
	apsd_result = smblib_get_apsd_result(chg);

	if (apsd_result->bit & QC_3P0_BIT) {
		/* for QC3, switch to CP if present */
	if ((apsd_result->bit & QC_3P0_BIT) && chg->sec_cp_present) {
		rc = smblib_select_sec_charger(chg, POWER_SUPPLY_CHARGER_SEC_CP,
		if (chg->sec_cp_present) {
			rc = smblib_select_sec_charger(chg,
				POWER_SUPPLY_CHARGER_SEC_CP,
				POWER_SUPPLY_CP_HVDCP3, false);
			if (rc < 0)
				dev_err(chg->dev,
			"Couldn't enable secondary chargers  rc=%d\n", rc);
				"Couldn't enable secondary chargers  rc=%d\n",
					rc);
		}

		/* QC3.5 detection timeout */
		if (!chg->apsd_ext_timeout &&
				!timer_pending(&chg->apsd_timer)) {
			smblib_dbg(chg, PR_MISC,
				"APSD Extented timer started at %lld\n",
				jiffies_to_msecs(jiffies));

			mod_timer(&chg->apsd_timer,
				msecs_to_jiffies(APSD_EXTENDED_TIMEOUT_MS)
				+ jiffies);
		}
	}

	smblib_dbg(chg, PR_INTERRUPT, "IRQ: hvdcp-3p0-auth-done rising; %s detected\n",
@@ -5968,6 +5988,9 @@ static void typec_src_removal(struct smb_charger *chg)
		smblib_notify_device_mode(chg, false);

	chg->typec_legacy = false;

	del_timer_sync(&chg->apsd_timer);
	chg->apsd_ext_timeout = false;
}

static void typec_mode_unattached(struct smb_charger *chg)
@@ -7159,6 +7182,17 @@ static enum alarmtimer_restart chg_termination_alarm_cb(struct alarm *alarm,
	return ALARMTIMER_NORESTART;
}

static void apsd_timer_cb(struct timer_list *tm)
{
	struct smb_charger *chg = container_of(tm, struct smb_charger,
							apsd_timer);

	smblib_dbg(chg, PR_MISC, "APSD Extented timer timeout at %lld\n",
			jiffies_to_msecs(jiffies));

	chg->apsd_ext_timeout = true;
}

static void jeita_update_work(struct work_struct *work)
{
	struct smb_charger *chg = container_of(work, struct smb_charger,
@@ -7610,6 +7644,7 @@ int smblib_init(struct smb_charger *chg)
					smblib_pr_swap_detach_work);
	INIT_DELAYED_WORK(&chg->pr_lock_clear_work,
					smblib_pr_lock_clear_work);
	timer_setup(&chg->apsd_timer, apsd_timer_cb, 0);

	if (chg->wa_flags & CHG_TERMINATION_WA) {
		INIT_WORK(&chg->chg_termination_work,
@@ -7747,6 +7782,7 @@ int smblib_deinit(struct smb_charger *chg)
			alarm_cancel(&chg->chg_termination_alarm);
			cancel_work_sync(&chg->chg_termination_work);
		}
		del_timer_sync(&chg->apsd_timer);
		cancel_work_sync(&chg->bms_update_work);
		cancel_work_sync(&chg->jeita_update_work);
		cancel_work_sync(&chg->pl_update_work);
+6 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
 */

#ifndef __SMB5_CHARGER_H
@@ -8,6 +8,7 @@
#include <linux/alarmtimer.h>
#include <linux/ktime.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/regulator/driver.h>
@@ -463,6 +464,8 @@ struct smb_charger {
	struct alarm		chg_termination_alarm;
	struct alarm		dcin_aicl_alarm;

	struct timer_list	apsd_timer;

	struct charger_param	chg_param;
	/* secondary charger config */
	bool			sec_pl_present;
@@ -561,6 +564,7 @@ struct smb_charger {
	bool			hvdcp3_standalone_config;
	bool			dcin_icl_user_set;
	bool			dpdm_enabled;
	bool			apsd_ext_timeout;

	/* workaround flag */
	u32			wa_flags;
@@ -777,6 +781,7 @@ int smblib_set_prop_rechg_soc_thresh(struct smb_charger *chg,
				const union power_supply_propval *val);
void smblib_suspend_on_debug_battery(struct smb_charger *chg);
int smblib_rerun_apsd_if_required(struct smb_charger *chg);
void smblib_rerun_apsd(struct smb_charger *chg);
int smblib_get_prop_fcc_delta(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_thermal_threshold(struct smb_charger *chg, u16 addr, int *val);