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

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

Merge "power: qpnp-qg: Add support for DC charging path"

parents 35743258 4f98a302
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -106,6 +106,7 @@ struct qpnp_qg {
	struct qg_user_data	udata;
	struct power_supply	*batt_psy;
	struct power_supply	*usb_psy;
	struct power_supply	*dc_psy;
	struct power_supply	*parallel_psy;
	struct qg_esr_data	esr_data[QG_MAX_ESR_COUNT];

@@ -120,6 +121,7 @@ struct qpnp_qg {
	bool			charge_done;
	bool			parallel_enabled;
	bool			usb_present;
	bool			dc_present;
	bool			charge_full;
	bool			force_soc;
	int			charge_status;
+7 −7
Original line number Diff line number Diff line
/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -134,8 +134,8 @@ static bool is_scaling_required(struct qpnp_qg *chip)
		return false;


	if (chip->catch_up_soc > chip->msoc && !is_usb_present(chip))
		/* USB is not present and SOC has increased */
	if (chip->catch_up_soc > chip->msoc && !is_input_present(chip))
		/* input is not present and SOC has increased */
		return false;

	return true;
@@ -169,11 +169,11 @@ static bool maint_soc_timeout(struct qpnp_qg *chip)
static void update_msoc(struct qpnp_qg *chip)
{
	int rc = 0, sdam_soc, batt_temp = 0,  batt_soc_32bit = 0;
	bool usb_present = is_usb_present(chip);
	bool input_present = is_input_present(chip);

	if (chip->catch_up_soc > chip->msoc) {
		/* SOC increased */
		if (usb_present) /* Increment if USB is present */
		if (input_present) /* Increment if input is present */
			chip->msoc += chip->dt.delta_soc;
	} else if (chip->catch_up_soc < chip->msoc) {
		/* SOC dropped */
@@ -213,14 +213,14 @@ static void update_msoc(struct qpnp_qg *chip)
						QG_SOC_FULL);
			cap_learning_update(chip->cl, batt_temp, batt_soc_32bit,
					chip->charge_status, chip->charge_done,
					usb_present, false);
					input_present, false);
		}
	}

	cycle_count_update(chip->counter,
			DIV_ROUND_CLOSEST(chip->msoc * 255, 100),
			chip->charge_status, chip->charge_done,
			usb_present);
			input_present);

	qg_dbg(chip, QG_DEBUG_SOC,
		"SOC scale: Update maint_soc=%d msoc=%d catch_up_soc=%d delta_soc=%d\n",
+29 −1
Original line number Diff line number Diff line
/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -275,6 +275,18 @@ static bool is_usb_available(struct qpnp_qg *chip)
	return true;
}

static bool is_dc_available(struct qpnp_qg *chip)
{
	if (chip->dc_psy)
		return true;

	chip->dc_psy = power_supply_get_by_name("dc");
	if (!chip->dc_psy)
		return false;

	return true;
}

bool is_usb_present(struct qpnp_qg *chip)
{
	union power_supply_propval pval = {0, };
@@ -286,6 +298,22 @@ bool is_usb_present(struct qpnp_qg *chip)
	return pval.intval ? true : false;
}

bool is_dc_present(struct qpnp_qg *chip)
{
	union power_supply_propval pval = {0, };

	if (is_dc_available(chip))
		power_supply_get_property(chip->dc_psy,
			POWER_SUPPLY_PROP_PRESENT, &pval);

	return pval.intval ? true : false;
}

bool is_input_present(struct qpnp_qg *chip)
{
	return is_usb_present(chip) || is_dc_present(chip);
}

static bool is_parallel_available(struct qpnp_qg *chip)
{
	if (chip->parallel_psy)
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -22,6 +22,8 @@ int get_sample_interval(struct qpnp_qg *chip, u32 *sample_interval);
int get_fifo_done_time(struct qpnp_qg *chip, bool rt, int *time_ms);
int get_rtc_time(unsigned long *rtc_time);
bool is_usb_present(struct qpnp_qg *chip);
bool is_dc_present(struct qpnp_qg *chip);
bool is_input_present(struct qpnp_qg *chip);
bool is_parallel_enabled(struct qpnp_qg *chip);
int qg_write_monotonic_soc(struct qpnp_qg *chip, int msoc);
int qg_get_battery_temp(struct qpnp_qg *chip, int *batt_temp);
+27 −18
Original line number Diff line number Diff line
@@ -1979,14 +1979,14 @@ static int qg_charge_full_update(struct qpnp_qg *chip)
	} else if ((!chip->charge_done || chip->msoc <= recharge_soc)
				&& chip->charge_full) {

		bool usb_present = is_usb_present(chip);
		bool input_present = is_input_present(chip);

		/*
		 * force a recharge only if SOC <= recharge SOC and
		 * we have not started charging.
		 */
		if ((chip->wa_flags & QG_RECHARGE_SOC_WA) &&
			usb_present && chip->msoc <= recharge_soc &&
			input_present && chip->msoc <= recharge_soc &&
			chip->charge_status != POWER_SUPPLY_STATUS_CHARGING) {
			/* Force recharge */
			prop.intval = 0;
@@ -2004,10 +2004,10 @@ static int qg_charge_full_update(struct qpnp_qg *chip)

		/*
		 * If SOC has indeed dropped below recharge-SOC or
		 * the USB is removed, if linearize-soc is set scale
		 * the input is removed, if linearize-soc is set scale
		 * msoc from 100% for better UX.
		 */
		if (chip->msoc < recharge_soc || !usb_present) {
		if (chip->msoc < recharge_soc || !input_present) {
			if (chip->dt.linearize_soc) {
				get_rtc_time(&chip->last_maint_soc_update_time);
				chip->maint_soc = FULL_SOC;
@@ -2018,9 +2018,9 @@ static int qg_charge_full_update(struct qpnp_qg *chip)
					chip->msoc, recharge_soc);
		} else {
			/* continue with charge_full state */
			qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full=%d usb_present=%d\n",
			qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full=%d input_present=%d\n",
					chip->msoc, recharge_soc,
					chip->charge_full, usb_present);
					chip->charge_full, input_present);
		}
	}
out:
@@ -2058,18 +2058,21 @@ static int qg_parallel_status_update(struct qpnp_qg *chip)
	return 0;
}

static int qg_usb_status_update(struct qpnp_qg *chip)
static int qg_input_status_update(struct qpnp_qg *chip)
{
	bool usb_present = is_usb_present(chip);
	bool dc_present = is_dc_present(chip);

	if (chip->usb_present != usb_present) {
	if ((chip->usb_present != usb_present) ||
		(chip->dc_present != dc_present)) {
		qg_dbg(chip, QG_DEBUG_STATUS,
			"USB status changed Present=%d\n",
							usb_present);
			"Input status changed usb_present=%d dc_present=%d\n",
						usb_present, dc_present);
		qg_scale_soc(chip, false);
	}

	chip->usb_present = usb_present;
	chip->dc_present = dc_present;

	return 0;
}
@@ -2183,6 +2186,7 @@ static void qg_status_change_work(struct work_struct *work)
			struct qpnp_qg, qg_status_change_work);
	union power_supply_propval prop = {0, };
	int rc = 0, batt_temp = 0, batt_soc_32b = 0;
	bool input_present = false;

	if (!is_batt_available(chip)) {
		pr_debug("batt-psy not available\n");
@@ -2221,14 +2225,17 @@ static void qg_status_change_work(struct work_struct *work)
	if (rc < 0)
		pr_err("Failed to update parallel-status, rc=%d\n", rc);

	rc = qg_usb_status_update(chip);
	rc = qg_input_status_update(chip);
	if (rc < 0)
		pr_err("Failed to update usb status, rc=%d\n", rc);
		pr_err("Failed to update input status, rc=%d\n", rc);

	/* get input status */
	input_present = is_input_present(chip);

	cycle_count_update(chip->counter,
			DIV_ROUND_CLOSEST(chip->msoc * 255, 100),
			chip->charge_status, chip->charge_done,
			chip->usb_present);
			input_present);

	if (!chip->dt.cl_disable) {
		rc = qg_get_battery_temp(chip, &batt_temp);
@@ -2240,14 +2247,14 @@ static void qg_status_change_work(struct work_struct *work)
					QG_SOC_FULL);
			cap_learning_update(chip->cl, batt_temp, batt_soc_32b,
				chip->charge_status, chip->charge_done,
				chip->usb_present, false);
				input_present, false);
		}
	}
	rc = qg_charge_full_update(chip);
	if (rc < 0)
		pr_err("Failed in charge_full_update, rc=%d\n", rc);

	ttf_update(chip->ttf, chip->usb_present);
	ttf_update(chip->ttf, input_present);
out:
	pm_relax(chip->dev);
}
@@ -2266,7 +2273,8 @@ static int qg_notifier_cb(struct notifier_block *nb,

	if ((strcmp(psy->desc->name, "battery") == 0)
		|| (strcmp(psy->desc->name, "parallel") == 0)
		|| (strcmp(psy->desc->name, "usb") == 0)) {
		|| (strcmp(psy->desc->name, "usb") == 0)
		|| (strcmp(psy->desc->name, "dc") == 0)) {
		/*
		 * We cannot vote for awake votable here as that takes
		 * a mutex lock and this is executed in an atomic context.
@@ -4040,8 +4048,9 @@ static int qpnp_qg_remove(struct platform_device *pdev)
static void qpnp_qg_shutdown(struct platform_device *pdev)
{
	struct qpnp_qg *chip = platform_get_drvdata(pdev);
	bool input_present = is_input_present(chip);

	if (!is_usb_present(chip) || !chip->profile_loaded)
	if (!input_present || !chip->profile_loaded)
		return;
	/*
	 * Charging status doesn't matter when the device shuts down and we
@@ -4050,7 +4059,7 @@ static void qpnp_qg_shutdown(struct platform_device *pdev)
	cycle_count_update(chip->counter,
			DIV_ROUND_CLOSEST(chip->msoc * 255, 100),
			POWER_SUPPLY_STATUS_NOT_CHARGING,
			true, chip->usb_present);
			true, input_present);
}

static const struct of_device_id match_table[] = {