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

Commit e33ed140 authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: smb1360: Add workaround for USB100 issue



Some SMB1360 v2.1 devices do not support the USB100
configuration due to an underlying hardware condition.
Disable setting the USB100 configuration for such devices.

While at it, set the register-controlled reset state of the
charger to USB500. This allows us to continue using the
existing USB100 / USB500 command-config values.

Change-Id: Ic05f289afee50371258950be0a0f831453f5882e
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent da6b67ea
Loading
Loading
Loading
Loading
+52 −15
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#define CFG_BATT_CHG_ICL_REG		0x05
#define AC_INPUT_ICL_PIN_BIT		BIT(7)
#define AC_INPUT_PIN_HIGH_BIT		BIT(6)
#define RESET_STATE_USB_500		BIT(5)
#define INPUT_CURR_LIM_MASK		SMB1360_MASK(3, 0)

#define CFG_GLITCH_FLT_REG		0x06
@@ -180,6 +181,7 @@
enum {
	WRKRND_FG_CONFIG_FAIL = BIT(0),
	WRKRND_BATT_DET_FAIL = BIT(1),
	WRKRND_USB100_FAIL = BIT(2),
};

enum {
@@ -411,6 +413,21 @@ static int smb1360_enable_volatile_writes(struct smb1360_chip *chip)
	return rc;
}

#define TRIM_1C_REG		0x1C
#define CHECK_USB100_GOOD_BIT	BIT(6)
static bool is_usb100_broken(struct smb1360_chip *chip)
{
	int rc;
	u8 reg;

	rc = smb1360_read(chip, TRIM_1C_REG, &reg);
	if (rc < 0) {
		dev_err(chip->dev, "Couldn't read trim 1C reg rc = %d\n", rc);
		return rc;
	}
	return !!(reg & CHECK_USB100_GOOD_BIT);
}

static int read_revision(struct smb1360_chip *chip, u8 *revision)
{
	int rc;
@@ -779,6 +796,12 @@ static int smb1360_set_appropriate_usb_current(struct smb1360_chip *chip)

	pr_debug("ICL set to = %d\n", input_current_limit[i]);

	if ((current_ma <= CURRENT_100_MA) &&
		(chip->workaround_flags & WRKRND_USB100_FAIL)) {
		pr_debug("usb100 not supported\n");
		current_ma = CURRENT_500_MA;
	}

	if (current_ma <= CURRENT_100_MA) {
		/* USB 100 */
		rc = smb1360_masked_write(chip, CMD_IL_REG,
@@ -1825,19 +1848,43 @@ static int smb1360_fg_config(struct smb1360_chip *chip)
	return 0;
}

static void smb1360_check_feature_support(struct smb1360_chip *chip)
{

	if (is_usb100_broken(chip)) {
		pr_debug("USB100 is not supported\n");
		chip->workaround_flags |= WRKRND_USB100_FAIL;
	}

	/*
	 * FG Configuration
	 *
	 * The REV_1 of the chip does not allow access to
	 * FG config registers (20-2FH). Set the workaround flag.
	 * Also, the battery detection does not work when the DCIN is absent,
	 * add a workaround flag for it.
	*/
	if (chip->revision == SMB1360_REV_1) {
		pr_debug("FG config and Battery detection is not supported\n");
		chip->workaround_flags |=
			WRKRND_FG_CONFIG_FAIL | WRKRND_BATT_DET_FAIL;
	}
}

static int smb1360_hw_init(struct smb1360_chip *chip)
{
	int rc;
	int i;
	u8 reg, mask;

	smb1360_check_feature_support(chip);

	rc = smb1360_enable_volatile_writes(chip);
	if (rc < 0) {
		dev_err(chip->dev, "Couldn't configure for volatile rc = %d\n",
				rc);
		return rc;
	}

	/*
	 * set chg en by cmd register, set chg en by writing bit 1,
	 * enable auto pre to fast
@@ -1855,8 +1902,10 @@ static int smb1360_hw_init(struct smb1360_chip *chip)
	/* USB/AC pin settings */
	rc = smb1360_masked_write(chip, CFG_BATT_CHG_ICL_REG,
					AC_INPUT_ICL_PIN_BIT
					| AC_INPUT_PIN_HIGH_BIT,
					AC_INPUT_PIN_HIGH_BIT);
					| AC_INPUT_PIN_HIGH_BIT
					| RESET_STATE_USB_500,
					AC_INPUT_PIN_HIGH_BIT
					| RESET_STATE_USB_500);
	if (rc < 0) {
		dev_err(chip->dev, "Couldn't set CFG_BATT_CHG_ICL_REG rc=%d\n",
				rc);
@@ -2061,18 +2110,6 @@ static int smb1360_hw_init(struct smb1360_chip *chip)
		}
	}

	/*
	 * FG Configuration
	 *
	 * The REV_1 of the chip does not allow access to
	 * FG config registers (20-2FH). Set the workaround flag.
	 * Also, the battery detection does not work when the DCIN is absent,
	 * add a workaround flag for it.
	*/

	if (chip->revision == SMB1360_REV_1)
		chip->workaround_flags |=
			WRKRND_FG_CONFIG_FAIL | WRKRND_BATT_DET_FAIL;

	smb1360_fg_config(chip);