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

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

Merge "power_supply: add HW_CURRENT_MAX power_supply property"

parents 6e2c59ad 17d9f038
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ static struct device_attribute power_supply_attrs[] = {
	POWER_SUPPLY_ATTR(die_health),
	POWER_SUPPLY_ATTR(connector_health),
	POWER_SUPPLY_ATTR(ctm_current_max),
	POWER_SUPPLY_ATTR(hw_current_max),
	/* Local extensions of type int64_t */
	POWER_SUPPLY_ATTR(charge_counter_ext),
	/* Properties of type `const char *' */
+36 −5
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ struct pl_data {
	struct votable		*pl_disable_votable;
	struct votable		*pl_awake_votable;
	struct votable		*hvdcp_hw_inov_dis_votable;
	struct votable		*usb_icl_votable;
	struct work_struct	status_change_work;
	struct work_struct	pl_disable_forever_work;
	struct delayed_work	pl_taper_work;
@@ -487,6 +488,25 @@ static int pl_fv_vote_callback(struct votable *votable, void *data,
	return 0;
}

static int usb_icl_vote_callback(struct votable *votable, void *data,
			int icl_ua, const char *client)
{
	struct pl_data *chip = data;
	union power_supply_propval pval = {0, };

	if (!chip->main_psy)
		return 0;

	if (client == NULL)
		icl_ua = INT_MAX;

	pval.intval = icl_ua;
	return power_supply_set_property(chip->main_psy,
				POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, &pval);

	return 0;
}

static void pl_disable_forever_work(struct work_struct *work)
{
	struct pl_data *chip = container_of(work,
@@ -596,13 +616,15 @@ static int pl_awake_vote_callback(struct votable *votable,

static bool is_main_available(struct pl_data *chip)
{
	if (!chip->main_psy)
	if (chip->main_psy)
		return true;

	chip->main_psy = power_supply_get_by_name("main");

	if (!chip->main_psy)
		return false;
	if (chip->main_psy)
		rerun_election(chip->usb_icl_votable);

	return true;
	return !!chip->main_psy;
}

static bool is_batt_available(struct pl_data *chip)
@@ -855,6 +877,14 @@ static int pl_init(void)
		goto destroy_votable;
	}

	chip->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN,
					usb_icl_vote_callback,
					chip);
	if (IS_ERR(chip->usb_icl_votable)) {
		rc = PTR_ERR(chip->usb_icl_votable);
		goto destroy_votable;
	}

	chip->pl_disable_votable = create_votable("PL_DISABLE", VOTE_SET_ANY,
					pl_disable_vote_callback,
					chip);
@@ -909,6 +939,7 @@ destroy_votable:
	destroy_votable(chip->pl_disable_votable);
	destroy_votable(chip->fv_votable);
	destroy_votable(chip->fcc_votable);
	destroy_votable(chip->usb_icl_votable);
release_wakeup_source:
	wakeup_source_unregister(chip->pl_ws);
cleanup:
+19 −0
Original line number Diff line number Diff line
@@ -616,6 +616,7 @@ static enum power_supply_property smb2_usb_main_props[] = {
	POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
	POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
	POWER_SUPPLY_PROP_FCC_DELTA,
	POWER_SUPPLY_PROP_CURRENT_MAX,
	/*
	 * TODO move the TEMP and TEMP_MAX properties here,
	 * and update the thermal balancer to look here
@@ -653,6 +654,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_FCC_DELTA:
		rc = smblib_get_prop_fcc_delta(chg, val);
		break;
	case POWER_SUPPLY_PROP_CURRENT_MAX:
		val->intval = get_effective_result(chg->usb_icl_votable);
		break;
	default:
		pr_debug("get prop %d is not supported in usb-main\n", psp);
		rc = -EINVAL;
@@ -683,6 +687,9 @@ static int smb2_usb_main_set_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
		rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval);
		break;
	case POWER_SUPPLY_PROP_CURRENT_MAX:
		rc = smblib_set_icl_current(chg, val->intval);
		break;
	default:
		pr_err("set prop %d is not supported\n", psp);
		rc = -EINVAL;
@@ -1572,6 +1579,16 @@ static int smb2_init_hw(struct smb2 *chip)
		return rc;
	}

	/* disable h/w autonomous parallel charging control */
	rc = smblib_masked_write(chg, MISC_CFG_REG,
				 STAT_PARALLEL_1400MA_EN_CFG_BIT, 0);
	if (rc < 0) {
		dev_err(chg->dev,
			"Couldn't disable h/w autonomous parallel control rc=%d\n",
			rc);
		return rc;
	}

	/* configure float charger options */
	switch (chip->dt.float_option) {
	case 1:
@@ -2230,6 +2247,8 @@ static int smb2_probe(struct platform_device *pdev)
	}
	batt_charge_type = val.intval;

	device_init_wakeup(chg->dev, true);

	pr_info("QPNP SMB2 probed successfully usb:present=%d type=%d batt:present = %d health = %d charge = %d\n",
		usb_present, chg->usb_psy_desc.type,
		batt_present, batt_health, batt_charge_type);
+53 −63
Original line number Diff line number Diff line
@@ -654,10 +654,13 @@ static void smblib_uusb_removal(struct smb_charger *chg)
{
	int rc;

	cancel_delayed_work_sync(&chg->pl_enable_work);
	vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0);
	vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);

	/* reset both usbin current and voltage votes */
	vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0);
	vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0);
	vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0);

	cancel_delayed_work_sync(&chg->hvdcp_detect_work);

@@ -795,29 +798,12 @@ static int smblib_get_pulse_cnt(struct smb_charger *chg, int *count)
	return 0;
}

/*********************
 * VOTABLE CALLBACKS *
 *********************/

static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data,
			int suspend, const char *client)
{
	struct smb_charger *chg = data;

	/* resume input if suspend is invalid */
	if (suspend < 0)
		suspend = 0;

	return smblib_set_dc_suspend(chg, (bool)suspend);
}

#define USBIN_25MA	25000
#define USBIN_100MA	100000
#define USBIN_150MA	150000
#define USBIN_500MA	500000
#define USBIN_900MA	900000


static int set_sdp_current(struct smb_charger *chg, int icl_ua)
{
	int rc;
@@ -856,20 +842,18 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua)
	return rc;
}

static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
			int icl_ua, const char *client)
int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
{
	struct smb_charger *chg = data;
	int rc = 0;
	bool override;
	union power_supply_propval pval;

	/* suspend and return if 25mA or less is requested */
	if (client && (icl_ua < USBIN_25MA))
	if (icl_ua < USBIN_25MA)
		return smblib_set_usb_suspend(chg, true);

	disable_irq_nosync(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq);
	if (!client)
	if (icl_ua == INT_MAX)
		goto override_suspend_config;

	rc = smblib_get_prop_typec_mode(chg, &pval);
@@ -898,7 +882,7 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
override_suspend_config:
	/* determine if override needs to be enforced */
	override = true;
	if (client == NULL) {
	if (icl_ua == INT_MAX) {
		/* remove override if no voters - hw defaults is desired */
		override = false;
	} else if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
@@ -936,6 +920,22 @@ enable_icl_changed_interrupt:
	return rc;
}

/*********************
 * VOTABLE CALLBACKS *
 *********************/

static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data,
			int suspend, const char *client)
{
	struct smb_charger *chg = data;

	/* resume input if suspend is invalid */
	if (suspend < 0)
		suspend = 0;

	return smblib_set_dc_suspend(chg, (bool)suspend);
}

static int smblib_dc_icl_vote_callback(struct votable *votable, void *data,
			int icl_ua, const char *client)
{
@@ -2618,16 +2618,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
			smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc);
			return rc;
		}

		/* pd active set, parallel charger can be enabled now */
		rc = vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER,
				false, 0);
		if (rc < 0) {
			smblib_err(chg,
				"Couldn't unvote PL_DELAY_HVDCP_VOTER rc=%d\n",
				rc);
			return rc;
		}
	}

	/* CC pin selection s/w override in PD session; h/w otherwise. */
@@ -3159,6 +3149,7 @@ irqreturn_t smblib_handle_usbin_uv(int irq, void *data)
	return IRQ_HANDLED;
}

#define PL_DELAY_MS			30000
irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
{
	struct smb_irq_data *irq_data = data;
@@ -3197,6 +3188,11 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
				smblib_err(chg, "Couldn't enable dpdm regulator rc=%d\n",
					rc);
		}

		/* Schedule work to enable parallel charger */
		vote(chg->awake_votable, PL_DELAY_VOTER, true, 0);
		schedule_delayed_work(&chg->pl_enable_work,
					msecs_to_jiffies(PL_DELAY_MS));
	} else {
		if (chg->wa_flags & BOOST_BACK_WA)
			vote(chg->usb_icl_votable, BOOST_BACK_VOTER, false, 0);
@@ -3374,9 +3370,6 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg,
		}
	}

	/* QC authentication done, parallel charger can be enabled now */
	vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0);

	smblib_dbg(chg, PR_INTERRUPT, "IRQ: hvdcp-3p0-auth-done rising; %s detected\n",
		   apsd_result->name);
}
@@ -3406,15 +3399,6 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg,
			/* enforce DCP ICL if specified */
			vote(chg->usb_icl_votable, DCP_VOTER,
				chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua);
		/*
		 * If adapter is not QC2.0/QC3.0 remove vote for parallel
		 * disable.
		 * Otherwise if adapter is QC2.0/QC3.0 wait for authentication
		 * to complete.
		 */
		if (!qc_charger)
			vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER,
					false, 0);
	}

	smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n",
@@ -3486,13 +3470,9 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
					true);
	case OCP_CHARGER_BIT:
	case FLOAT_CHARGER_BIT:
		/*
		 * if not DCP then no hvdcp timeout happens. Enable
		 * pd/parallel here.
		 */
		/* if not DCP then no hvdcp timeout happens, Enable pd here. */
		vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER,
				false, 0);
		vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0);
		break;
	case DCP_CHARGER_BIT:
		if (chg->wa_flags & QC_CHARGER_DETECTION_WA_BIT)
@@ -3645,9 +3625,12 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
{
	int rc;

	cancel_delayed_work_sync(&chg->pl_enable_work);
	vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0);
	vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);

	vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0);
	vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0);
	vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0);
	vote(chg->usb_irq_enable_votable, PD_VOTER, false, 0);
	vote(chg->usb_irq_enable_votable, QC_VOTER, false, 0);

@@ -3703,8 +3686,6 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg,
	if (rp == POWER_SUPPLY_TYPEC_SOURCE_HIGH
			|| rp == POWER_SUPPLY_TYPEC_NON_COMPLIANT) {
		smblib_dbg(chg, PR_MISC, "VBUS & CC could be shorted; keeping HVDCP disabled\n");
		/* HVDCP is not going to be enabled; enable parallel */
		vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0);
		vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
								true, 0);
	} else {
@@ -4210,6 +4191,16 @@ static void smblib_icl_change_work(struct work_struct *work)
	smblib_dbg(chg, PR_INTERRUPT, "icl_settled=%d\n", settled_ua);
}

static void smblib_pl_enable_work(struct work_struct *work)
{
	struct smb_charger *chg = container_of(work, struct smb_charger,
							pl_enable_work.work);

	smblib_dbg(chg, PR_PARALLEL, "timer expired, enabling parallel\n");
	vote(chg->pl_disable_votable, PL_DELAY_VOTER, false, 0);
	vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);
}

static int smblib_create_votables(struct smb_charger *chg)
{
	int rc = 0;
@@ -4226,13 +4217,19 @@ static int smblib_create_votables(struct smb_charger *chg)
		return rc;
	}

	chg->usb_icl_votable = find_votable("USB_ICL");
	if (!chg->usb_icl_votable) {
		rc = -EPROBE_DEFER;
		return rc;
	}

	chg->pl_disable_votable = find_votable("PL_DISABLE");
	if (!chg->pl_disable_votable) {
		rc = -EPROBE_DEFER;
		return rc;
	}
	vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0);
	vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0);
	vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0);

	chg->dc_suspend_votable = create_votable("DC_SUSPEND", VOTE_SET_ANY,
					smblib_dc_suspend_vote_callback,
@@ -4242,14 +4239,6 @@ static int smblib_create_votables(struct smb_charger *chg)
		return rc;
	}

	chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN,
					smblib_usb_icl_vote_callback,
					chg);
	if (IS_ERR(chg->usb_icl_votable)) {
		rc = PTR_ERR(chg->usb_icl_votable);
		return rc;
	}

	chg->dc_icl_votable = create_votable("DC_ICL", VOTE_MIN,
					smblib_dc_icl_vote_callback,
					chg);
@@ -4400,6 +4389,7 @@ int smblib_init(struct smb_charger *chg)
	INIT_WORK(&chg->vconn_oc_work, smblib_vconn_oc_work);
	INIT_DELAYED_WORK(&chg->otg_ss_done_work, smblib_otg_ss_done_work);
	INIT_DELAYED_WORK(&chg->icl_change_work, smblib_icl_change_work);
	INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work);
	chg->fake_capacity = -EINVAL;

	switch (chg->mode) {
+3 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ enum print_reason {
#define MICRO_USB_VOTER			"MICRO_USB_VOTER"
#define DEBUG_BOARD_VOTER		"DEBUG_BOARD_VOTER"
#define PD_SUSPEND_SUPPORTED_VOTER	"PD_SUSPEND_SUPPORTED_VOTER"
#define PL_DELAY_HVDCP_VOTER		"PL_DELAY_HVDCP_VOTER"
#define PL_DELAY_VOTER			"PL_DELAY_VOTER"
#define CTM_VOTER			"CTM_VOTER"
#define SW_QC3_VOTER			"SW_QC3_VOTER"
#define AICL_RERUN_VOTER		"AICL_RERUN_VOTER"
@@ -288,6 +288,7 @@ struct smb_charger {
	struct work_struct	vconn_oc_work;
	struct delayed_work	otg_ss_done_work;
	struct delayed_work	icl_change_work;
	struct delayed_work	pl_enable_work;

	/* cached status */
	int			voltage_min_uv;
@@ -491,6 +492,7 @@ int smblib_icl_override(struct smb_charger *chg, bool override);
int smblib_set_icl_reduction(struct smb_charger *chg, int reduction_ua);
int smblib_dp_dm(struct smb_charger *chg, int val);
int smblib_rerun_aicl(struct smb_charger *chg);
int smblib_set_icl_current(struct smb_charger *chg, int icl_ua);

int smblib_init(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);
Loading