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

Commit e1b5b678 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 QG reset"

parents b7cc56a7 5a4dd0ce
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -387,6 +387,7 @@ static struct device_attribute power_supply_attrs[] = {
	POWER_SUPPLY_ATTR(fcc_stepper_enable),
	POWER_SUPPLY_ATTR(toggle_stat),
	POWER_SUPPLY_ATTR(main_fcc_max),
	POWER_SUPPLY_ATTR(fg_reset),
	/* Charge pump properties */
	POWER_SUPPLY_ATTR(cp_status1),
	POWER_SUPPLY_ATTR(cp_status2),
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ struct qpnp_qg {
	bool			parallel_enabled;
	bool			usb_present;
	bool			charge_full;
	bool			force_soc;
	int			charge_status;
	int			charge_type;
	int			chg_iterm_ma;
+3 −0
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@
#define QG_INT_LATCHED_STS_REG			0x18
#define FIFO_UPDATE_DONE_INT_LAT_STS_BIT	BIT(3)

#define QG_STATE_TRIG_CMD_REG			0x40
#define S7_PON_OCV_START			BIT(3)

#define QG_DATA_CTL1_REG			0x41
#define MASTER_HOLD_OR_CLR_BIT			BIT(0)

+95 −2
Original line number Diff line number Diff line
@@ -1048,7 +1048,8 @@ static void process_udata_work(struct work_struct *work)
			chip->catch_up_soc = chip->udata.param[QG_SOC].data;
		}

		qg_scale_soc(chip, false);
		qg_scale_soc(chip, chip->force_soc);
		chip->force_soc = false;

		/* update parameters to SDAM */
		chip->sdam_data[SDAM_SOC] = chip->msoc;
@@ -1631,6 +1632,94 @@ static int qg_ttf_awake_voter(void *data, bool val)
	return 0;
}

#define MAX_QG_OK_RETRIES	20
static int qg_reset(struct qpnp_qg *chip)
{
	int rc = 0, count = 0, soc = 0;
	u32 ocv_uv = 0, ocv_raw = 0;
	u8 reg = 0;

	qg_dbg(chip, QG_DEBUG_STATUS, "QG RESET triggered\n");

	mutex_lock(&chip->data_lock);

	/* hold and release master to clear FIFO's */
	rc = qg_master_hold(chip, true);
	if (rc < 0) {
		pr_err("Failed to hold master, rc=%d\n", rc);
		goto done;
	}

	/* delay for the master-hold */
	msleep(20);

	rc = qg_master_hold(chip, false);
	if (rc < 0) {
		pr_err("Failed to release master, rc=%d\n", rc);
		goto done;
	}

	/* delay for master to settle */
	msleep(20);

	qg_get_battery_voltage(chip, &rc);
	qg_get_battery_capacity(chip, &soc);
	qg_dbg(chip, QG_DEBUG_STATUS, "VBAT=%duV SOC=%d\n", rc, soc);

	/* Trigger S7 */
	rc = qg_masked_write(chip, chip->qg_base + QG_STATE_TRIG_CMD_REG,
				S7_PON_OCV_START, S7_PON_OCV_START);
	if (rc < 0) {
		pr_err("Failed to trigger S7, rc=%d\n", rc);
		goto done;
	}

	/* poll for QG OK */
	do {
		rc = qg_read(chip, chip->qg_base + QG_STATUS1_REG, &reg, 1);
		if (rc < 0) {
			pr_err("Failed to read STATUS1_REG rc=%d\n", rc);
			goto done;
		}

		if (reg & QG_OK_BIT)
			break;

		msleep(200);
		count++;
	} while (count < MAX_QG_OK_RETRIES);

	if (count == MAX_QG_OK_RETRIES) {
		qg_dbg(chip, QG_DEBUG_STATUS, "QG_OK not set\n");
		goto done;
	}

	/* read S7 PON OCV */
	rc = qg_read_ocv(chip, &ocv_uv, &ocv_raw, S7_PON_OCV);
	if (rc < 0) {
		pr_err("Failed to read PON OCV rc=%d\n", rc);
		goto done;
	}

	qg_dbg(chip, QG_DEBUG_STATUS, "S7_OCV = %duV\n", ocv_uv);

	chip->kdata.param[QG_GOOD_OCV_UV].data = ocv_uv;
	chip->kdata.param[QG_GOOD_OCV_UV].valid = true;
	/* clear all the userspace data */
	chip->kdata.param[QG_CLEAR_LEARNT_DATA].data = 1;
	chip->kdata.param[QG_CLEAR_LEARNT_DATA].valid = true;

	vote(chip->awake_votable, GOOD_OCV_VOTER, true, 0);
	/* signal the read thread */
	chip->data_ready = true;
	chip->force_soc = true;
	wake_up_interruptible(&chip->qg_wait_q);

done:
	mutex_unlock(&chip->data_lock);
	return rc;
}

static int qg_psy_set_property(struct power_supply *psy,
			       enum power_supply_property psp,
			       const union power_supply_propval *pval)
@@ -1669,6 +1758,9 @@ static int qg_psy_set_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_ESR_NOMINAL:
		chip->esr_nominal = pval->intval;
		break;
	case POWER_SUPPLY_PROP_FG_RESET:
		qg_reset(chip);
		break;
	default:
		break;
	}
@@ -1793,6 +1885,7 @@ static int qg_property_is_writeable(struct power_supply *psy,
	case POWER_SUPPLY_PROP_ESR_ACTUAL:
	case POWER_SUPPLY_PROP_ESR_NOMINAL:
	case POWER_SUPPLY_PROP_SOH:
	case POWER_SUPPLY_PROP_FG_RESET:
		return 1;
	default:
		break;
@@ -1827,6 +1920,7 @@ static enum power_supply_property qg_psy_props[] = {
	POWER_SUPPLY_PROP_ESR_ACTUAL,
	POWER_SUPPLY_PROP_ESR_NOMINAL,
	POWER_SUPPLY_PROP_SOH,
	POWER_SUPPLY_PROP_FG_RESET,
};

static const struct power_supply_desc qg_psy_desc = {
@@ -1993,7 +2087,6 @@ static int qg_handle_battery_removal(struct qpnp_qg *chip)
	return rc;
}

#define MAX_QG_OK_RETRIES	20
static int qg_handle_battery_insertion(struct qpnp_qg *chip)
{
	int rc, count = 0;
+1 −0
Original line number Diff line number Diff line
@@ -312,6 +312,7 @@ enum power_supply_property {
	POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE,
	POWER_SUPPLY_PROP_TOGGLE_STAT,
	POWER_SUPPLY_PROP_MAIN_FCC_MAX,
	POWER_SUPPLY_PROP_FG_RESET,
	/* Charge pump properties */
	POWER_SUPPLY_PROP_CP_STATUS1,
	POWER_SUPPLY_PROP_CP_STATUS2,