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

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

Merge "qcom: smb2: Disable parallel charging on qnovo charging below 2A"

parents 3b758d49 cfe86e48
Loading
Loading
Loading
Loading
+97 −46
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#define QNOVO_PTRAIN_STS	0x08
#define QNOVO_ERROR_STS		0x09
#define QNOVO_ERROR_BIT		BIT(0)
#define QNOVO_ERROR_STS2	0x0A
#define QNOVO_INT_RT_STS	0x10
#define QNOVO_INT_SET_TYPE	0x11
#define QNOVO_INT_POLARITY_HIGH	0x12
@@ -272,28 +273,22 @@ static int qnovo_disable_cb(struct votable *votable, void *data, int disable,
					const char *client)
{
	struct qnovo *chip = data;
	int rc = 0;
	union power_supply_propval pval = {0};
	int rc;

	if (disable) {
		rc = qnovo_batt_psy_update(chip, true);
		if (rc < 0)
			return rc;
	}
	if (!is_batt_available(chip))
		return -EINVAL;

	rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
				 disable ? 0 : QNOVO_PTRAIN_EN_BIT);
	pval.intval = !disable;
	rc = power_supply_set_property(chip->batt_psy,
			POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE,
			&pval);
	if (rc < 0) {
		dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n",
			disable ? "disable" : "enable", rc);
		return rc;
	}

	if (!disable) {
		rc = qnovo_batt_psy_update(chip, false);
		if (rc < 0)
			return rc;
		pr_err("Couldn't set prop qnovo_enable rc = %d\n", rc);
		return -EINVAL;
	}

	rc = qnovo_batt_psy_update(chip, disable);
	return rc;
}

@@ -348,13 +343,15 @@ static int qnovo_check_chg_version(struct qnovo *chip)
enum {
	VER = 0,
	OK_TO_QNOVO,
	ENABLE,
	QNOVO_ENABLE,
	PT_ENABLE,
	FV_REQUEST,
	FCC_REQUEST,
	PE_CTRL_REG,
	PE_CTRL2_REG,
	PTRAIN_STS_REG,
	INT_RT_STS_REG,
	ERR_STS2_REG,
	PREST1,
	PPULS1,
	NREST1,
@@ -394,6 +391,12 @@ struct param_info {
};

static struct param_info params[] = {
	[PT_ENABLE] = {
		.name			= "PT_ENABLE",
		.start_addr		= QNOVO_PTRAIN_EN,
		.num_regs		= 1,
		.units_str		= "",
	},
	[FV_REQUEST] = {
		.units_str		= "uV",
	},
@@ -424,6 +427,12 @@ static struct param_info params[] = {
		.num_regs		= 1,
		.units_str		= "",
	},
	[ERR_STS2_REG] = {
		.name			= "RAW_CHGR_ERR",
		.start_addr		= QNOVO_ERROR_STS2,
		.num_regs		= 1,
		.units_str		= "",
	},
	[PREST1] = {
		.name			= "PREST1",
		.start_addr		= QNOVO_PREST1_CTRL,
@@ -648,30 +657,70 @@ static ssize_t ok_to_qnovo_show(struct class *c, struct class_attribute *attr,
	return snprintf(buf, PAGE_SIZE, "%d\n", chip->cs.ok_to_qnovo);
}

static ssize_t enable_show(struct class *c, struct class_attribute *attr,
static ssize_t qnovo_enable_show(struct class *c, struct class_attribute *attr,
			char *ubuf)
{
	struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
	int val;
	int val = get_effective_result(chip->disable_votable);

	val = get_client_vote(chip->disable_votable, USER_VOTER);
	val = !val;
	return snprintf(ubuf, PAGE_SIZE, "%d\n", val);
	return snprintf(ubuf, PAGE_SIZE, "%d\n", !val);
}

static ssize_t qnovo_enable_store(struct class *c, struct class_attribute *attr,
			const char *ubuf, size_t count)
{
	struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
	unsigned long val;

	if (kstrtoul(ubuf, 0, &val))
		return -EINVAL;

	vote(chip->disable_votable, USER_VOTER, !val, 0);

	return count;
}

static ssize_t enable_store(struct class *c, struct class_attribute *attr,
static ssize_t pt_enable_show(struct class *c, struct class_attribute *attr,
			char *ubuf)
{
	int i = attr - qnovo_attributes;
	struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
	u8 buf[2] = {0, 0};
	u16 regval;
	int rc;

	rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs);
	if (rc < 0) {
		pr_err("Couldn't read %s rc = %d\n", params[i].name, rc);
		return -EINVAL;
	}
	regval = buf[1] << 8 | buf[0];

	return snprintf(ubuf, PAGE_SIZE, "%d\n",
				(int)(regval & QNOVO_PTRAIN_EN_BIT));
}

static ssize_t pt_enable_store(struct class *c, struct class_attribute *attr,
			const char *ubuf, size_t count)
{
	struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
	unsigned long val;
	bool disable;
	int rc = 0;

	if (get_effective_result(chip->disable_votable))
		return -EINVAL;

	if (kstrtoul(ubuf, 0, &val))
		return -EINVAL;

	disable = !val;
	rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
				 (bool)val ? QNOVO_PTRAIN_EN_BIT : 0);
	if (rc < 0) {
		dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n",
			(bool)val ? "enable" : "disable", rc);
		return rc;
	}

	vote(chip->disable_votable, USER_VOTER, disable, 0);
	return count;
}

@@ -698,6 +747,9 @@ static ssize_t val_store(struct class *c, struct class_attribute *attr,
	int i = attr - qnovo_attributes;
	unsigned long val;

	if (get_effective_result(chip->disable_votable))
		return -EINVAL;

	if (kstrtoul(ubuf, 0, &val))
		return -EINVAL;

@@ -707,6 +759,8 @@ static ssize_t val_store(struct class *c, struct class_attribute *attr,
	if (i == FCC_REQUEST)
		chip->fcc_uA_request = val;

	qnovo_batt_psy_update(chip, false);

	return count;
}

@@ -1016,8 +1070,8 @@ static ssize_t batt_prop_show(struct class *c, struct class_attribute *attr,
static struct class_attribute qnovo_attributes[] = {
	[VER]			= __ATTR_RO(version),
	[OK_TO_QNOVO]		= __ATTR_RO(ok_to_qnovo),
	[ENABLE]		= __ATTR(enable, 0644,
					enable_show, enable_store),
	[QNOVO_ENABLE]		= __ATTR_RW(qnovo_enable),
	[PT_ENABLE]		= __ATTR_RW(pt_enable),
	[FV_REQUEST]		= __ATTR(fv_uV_request, 0644,
					val_show, val_store),
	[FCC_REQUEST]		= __ATTR(fcc_uA_request, 0644,
@@ -1030,6 +1084,8 @@ static struct class_attribute qnovo_attributes[] = {
					reg_show, NULL),
	[INT_RT_STS_REG]	= __ATTR(INT_RT_STS_REG, 0444,
					reg_show, NULL),
	[ERR_STS2_REG]		= __ATTR(ERR_STS2_REG, 0444,
					reg_show, NULL),
	[PREST1]		= __ATTR(PREST1_mS, 0644,
					time_show, time_store),
	[PPULS1]		= __ATTR(PPULS1_uC, 0644,
@@ -1050,7 +1106,7 @@ static struct class_attribute qnovo_attributes[] = {
					time_show, NULL),
	[PREST2]		= __ATTR(PREST2_mS, 0644,
					time_show, time_store),
	[PPULS2]		= __ATTR(PPULS2_mS, 0644,
	[PPULS2]		= __ATTR(PPULS2_uC, 0644,
					coulomb_show, coulomb_store),
	[NREST2]		= __ATTR(NREST2_mS, 0644,
					time_show, time_store),
@@ -1135,8 +1191,7 @@ static void get_chg_status(struct qnovo *chip, const struct chg_props *cp,
{
	cs->ok_to_qnovo = false;

	if (cp->charging &&
		(cp->usb_online || cp->dc_online))
	if (cp->charging && (cp->usb_online || cp->dc_online))
		cs->ok_to_qnovo = true;
}

@@ -1152,17 +1207,10 @@ static void status_change_work(struct work_struct *work)
	get_chg_status(chip, &cp, &cs);

	if (cs.ok_to_qnovo ^ chip->cs.ok_to_qnovo) {
		/*
		 * when it is not okay to Qnovo charge, disable both voters,
		 * so that when it becomes okay to Qnovo charge the user voter
		 * has to specifically enable its vote to being Qnovo charging
		 */
		if (!cs.ok_to_qnovo) {
			vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 1, 0);
			vote(chip->disable_votable, USER_VOTER, 1, 0);
		} else {
			vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 0, 0);
		}
		vote(chip->disable_votable, OK_TO_QNOVO_VOTER,
			!cs.ok_to_qnovo, 0);
		if (!cs.ok_to_qnovo)
			vote(chip->disable_votable, USER_VOTER, true, 0);
		notify_uevent = true;
	}

@@ -1192,8 +1240,6 @@ static irqreturn_t handle_ptrain_done(int irq, void *data)
{
	struct qnovo *chip = data;

	/* disable user voter here */
	vote(chip->disable_votable, USER_VOTER, 0, 0);
	kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
	return IRQ_HANDLED;
}
@@ -1206,7 +1252,7 @@ static int qnovo_hw_init(struct qnovo *chip)
	u8 vadc_offset, vadc_gain;
	u8 val;

	vote(chip->disable_votable, USER_VOTER, 1, 0);
	vote(chip->disable_votable, USER_VOTER, true, 0);

	val = 0;
	rc = qnovo_write(chip, QNOVO_STRM_CTRL, &val, 1);
@@ -1318,6 +1364,9 @@ static int qnovo_request_interrupts(struct qnovo *chip)
					irq_ptrain_done, rc);
		return rc;
	}

	enable_irq_wake(irq_ptrain_done);

	return rc;
}

@@ -1399,6 +1448,8 @@ static int qnovo_probe(struct platform_device *pdev)
		goto unreg_notifier;
	}

	device_init_wakeup(chip->dev, true);

	return rc;

unreg_notifier:
+2 −0
Original line number Diff line number Diff line
@@ -999,6 +999,8 @@ static int smb2_batt_set_prop(struct power_supply *psy,
		break;
	case POWER_SUPPLY_PROP_CURRENT_QNOVO:
		chg->qnovo_fcc_ua = val->intval;
		vote(chg->pl_disable_votable, PL_QNOVO_VOTER,
			val->intval != -EINVAL && val->intval < 2000000, 0);
		rc = rerun_election(chg->fcc_votable);
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ enum print_reason {
#define USB_PSY_VOTER			"USB_PSY_VOTER"
#define PL_TAPER_WORK_RUNNING_VOTER	"PL_TAPER_WORK_RUNNING_VOTER"
#define PL_INDIRECT_VOTER		"PL_INDIRECT_VOTER"
#define PL_QNOVO_VOTER			"PL_QNOVO_VOTER"
#define USBIN_I_VOTER			"USBIN_I_VOTER"
#define USBIN_V_VOTER			"USBIN_V_VOTER"
#define CHG_STATE_VOTER			"CHG_STATE_VOTER"