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

Commit 2fb34d69 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy Committed by Matt Wagantall
Browse files

power: qpnp-smbcharger: add support for configuring OTG pulse skip



In OTG mode, when there is no load and flash is being enabled, it
causes a voltage dip at USB_IN and cause OTG device not to work.
To avoid such scenarios, OTG pulse skip should be enabled before
the flash is enabled. Also, before the flash is disabled, OTG
pulse skip should be disabled. Add support for this through the
power supply property flash_active.

CRs-Fixed: 793295
Change-Id: Ieb81fe039ce3b98ddc6942531a751cc287ab0a71
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 43621f9f
Loading
Loading
Loading
Loading
+47 −6
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ struct smbchg_chip {
	bool				safety_timer_en;
	bool				aicl_complete;
	bool				usb_ov_det;
	bool				otg_pulse_skip_en;

	/* jeita and temperature */
	bool				batt_hot;
@@ -712,6 +713,7 @@ static enum power_supply_property smbchg_battery_properties[] = {
	POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE,
	POWER_SUPPLY_PROP_INPUT_CURRENT_MAX,
	POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
	POWER_SUPPLY_PROP_FLASH_ACTIVE,
};

#define CHGR_STS			0x0E
@@ -2546,6 +2548,40 @@ static int smbchg_safety_timer_enable(struct smbchg_chip *chip, bool enable)
	return 0;
}

#define OTG_TRIM6		0xF6
#define TR_ENB_SKIP_BIT		BIT(2)
#define OTG_EN_BIT		BIT(0)
static int smbchg_otg_pulse_skip_enable(struct smbchg_chip *chip, bool enable)
{
	int rc;
	u8 reg;

	if (enable == chip->otg_pulse_skip_en)
		return 0;

	rc = smbchg_read(chip, &reg, chip->bat_if_base + CMD_CHG_REG, 1);
	if (rc < 0) {
		dev_err(chip->dev,
				"Couldn't read OTG enable bit rc=%d\n", rc);
		return rc;
	}

	/* If OTG is not enabled, don't set OTG pulse skip enable */
	if (!(reg & OTG_EN_BIT))
		return 0;

	rc = smbchg_sec_masked_write(chip, chip->otg_base + OTG_TRIM6,
			TR_ENB_SKIP_BIT, enable ? TR_ENB_SKIP_BIT : 0);
	if (rc < 0) {
		dev_err(chip->dev,
			"Couldn't %s otg pulse skip rc = %d\n",
			enable ? "enable" : "disable", rc);
		return rc;
	}
	chip->otg_pulse_skip_en = enable;
	return 0;
}

static int smbchg_battery_set_property(struct power_supply *psy,
				       enum power_supply_property prop,
				       const union power_supply_propval *val)
@@ -2582,6 +2618,9 @@ static int smbchg_battery_set_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
		rc = smbchg_safety_timer_enable(chip, val->intval);
		break;
	case POWER_SUPPLY_PROP_FLASH_ACTIVE:
		rc = smbchg_otg_pulse_skip_enable(chip, val->intval);
		break;
	default:
		return -EINVAL;
	}
@@ -2677,6 +2716,9 @@ static int smbchg_battery_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
		val->intval = chip->safety_timer_en;
		break;
	case POWER_SUPPLY_PROP_FLASH_ACTIVE:
		val->intval = chip->otg_pulse_skip_en;
		break;
	default:
		return -EINVAL;
	}
@@ -3065,7 +3107,6 @@ static void smbchg_external_power_changed(struct power_supply *psy)
	power_supply_changed(&chip->batt_psy);
}

#define OTG_EN		BIT(0)
static int smbchg_otg_regulator_enable(struct regulator_dev *rdev)
{
	int rc = 0;
@@ -3073,7 +3114,7 @@ static int smbchg_otg_regulator_enable(struct regulator_dev *rdev)

	chip->otg_retries = 0;
	rc = smbchg_masked_write(chip, chip->bat_if_base + CMD_CHG_REG,
			OTG_EN, OTG_EN);
			OTG_EN_BIT, OTG_EN_BIT);
	if (rc < 0)
		dev_err(chip->dev, "Couldn't enable OTG mode rc=%d\n", rc);
	else
@@ -3088,7 +3129,7 @@ static int smbchg_otg_regulator_disable(struct regulator_dev *rdev)
	struct smbchg_chip *chip = rdev_get_drvdata(rdev);

	rc = smbchg_masked_write(chip, chip->bat_if_base + CMD_CHG_REG,
			OTG_EN, 0);
			OTG_EN_BIT, 0);
	if (rc < 0)
		dev_err(chip->dev, "Couldn't disable OTG mode rc=%d\n", rc);
	pr_smb(PR_STATUS, "Disabling OTG Boost\n");
@@ -3108,7 +3149,7 @@ static int smbchg_otg_regulator_is_enable(struct regulator_dev *rdev)
		return rc;
	}

	return (reg & OTG_EN) ? 1 : 0;
	return (reg & OTG_EN_BIT) ? 1 : 0;
}

struct regulator_ops smbchg_otg_reg_ops = {
@@ -4176,10 +4217,10 @@ static irqreturn_t otg_oc_handler(int irq, void *_chip)
			"Retrying OTG enable. Try #%d, elapsed_us %lld\n",
						chip->otg_retries, elapsed_us);
		smbchg_masked_write(chip, chip->bat_if_base + CMD_CHG_REG,
							OTG_EN, 0);
							OTG_EN_BIT, 0);
		msleep(20);
		smbchg_masked_write(chip, chip->bat_if_base + CMD_CHG_REG,
							OTG_EN, OTG_EN);
							OTG_EN_BIT, OTG_EN_BIT);
		chip->otg_enable_time = ktime_get();
	}
	return IRQ_HANDLED;