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

Commit e7b6f1f1 authored by Anirudh Ghayal's avatar Anirudh Ghayal Committed by Ashay Jaiswal
Browse files

power: qpnp-charger: Use VCHG to read input current



The VCHG can be configured to track the current drawn by the
charger at its input (IUSB). The voltage at VCHG is proportional
to the IUSB.

PMI8950 - VCHG is internally routed to a VADC channel.
PMI8994 - The VCHG pin can be externally routed to VADC via a MPP

CRs-Fixed: 930343
Change-Id: I4c299c92d6405f65f1280655c8a5d004ef401d38
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 71e1c53f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -282,6 +282,8 @@ Optional Properties:
- qcom,skip-usb-suspend-for-fake-battery	A boolean property to skip
						suspending USB path for fake
						battery.
- qcom,vchg_sns-vadc		Phandle of the VADC node.
- qcom,vchg-adc-channel-id	The ADC channel to which the VCHG is routed.

Example:
	qcom,qpnp-smbcharger {
@@ -299,6 +301,8 @@ Example:
		qcom,bms-psy-name = "bms";
		qcom,battery-psy-name = "battery";
		qcom,thermal-mitigation = <1500 700 600 325>;
		qcom,vchg_sns-vadc = <&pmi8950_vadc>;
		qcom,vchg-adc-channel-id = <3>;

		qcom,chgr@1000 {
			reg = <0x1000 0x100>;
+60 −1
Original line number Diff line number Diff line
@@ -258,6 +258,8 @@ struct smbchg_chip {
	int				pulse_cnt;
	struct led_classdev		led_cdev;
	bool				skip_usb_notification;
	u32				vchg_adc_channel;
	struct qpnp_vadc_chip		*vchg_vadc_dev;

	/* voters */
	struct votable			*fcc_votable;
@@ -5343,6 +5345,31 @@ static int smbchg_dp_dm(struct smbchg_chip *chip, int val)
	return rc;
}

#define CHARGE_OUTPUT_VTG_RATIO		840
static int smbchg_get_iusb(struct smbchg_chip *chip)
{
	int rc, iusb_ua = -EINVAL;
	struct qpnp_vadc_result adc_result;

	if (!is_usb_present(chip) && !is_dc_present(chip))
		return 0;

	if (chip->vchg_vadc_dev && chip->vchg_adc_channel != -EINVAL) {
		rc = qpnp_vadc_read(chip->vchg_vadc_dev,
				chip->vchg_adc_channel, &adc_result);
		if (rc) {
			pr_smb(PR_STATUS,
				"error in VCHG (channel-%d) read rc = %d\n",
						chip->vchg_adc_channel, rc);
			return 0;
		}
		iusb_ua = div_s64(adc_result.physical * 1000,
						CHARGE_OUTPUT_VTG_RATIO);
	}

	return iusb_ua;
}

static enum power_supply_property smbchg_battery_properties[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_PRESENT,
@@ -5363,6 +5390,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_INPUT_CURRENT_NOW,
	POWER_SUPPLY_PROP_FLASH_ACTIVE,
	POWER_SUPPLY_PROP_FLASH_TRIGGER,
	POWER_SUPPLY_PROP_DP_DM,
@@ -5545,6 +5573,9 @@ static int smbchg_battery_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_RERUN_AICL:
		val->intval = 0;
		break;
	case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW:
		val->intval = smbchg_get_iusb(chip);
		break;
	default:
		return -EINVAL;
	}
@@ -6289,6 +6320,8 @@ static inline int get_bpd(const char *name)
#define PIN_SRC_SHIFT			0
#define CHGR_CFG			0xFF
#define RCHG_LVL_BIT			BIT(0)
#define VCHG_EN_BIT			BIT(1)
#define VCHG_INPUT_CURRENT_BIT		BIT(3)
#define CFG_AFVC			0xF6
#define VFLOAT_COMP_ENABLE_MASK		SMB_MASK(2, 0)
#define TR_RID_REG			0xFA
@@ -6601,6 +6634,18 @@ static int smbchg_hw_init(struct smbchg_chip *chip)
		return rc;
	}

	if (chip->vchg_adc_channel != -EINVAL) {
		/* configure and enable VCHG */
		rc = smbchg_sec_masked_write(chip, chip->chgr_base + CHGR_CFG,
				VCHG_INPUT_CURRENT_BIT | VCHG_EN_BIT,
				VCHG_INPUT_CURRENT_BIT | VCHG_EN_BIT);
		if (rc < 0) {
			dev_err(chip->dev, "Couldn't set recharge rc = %d\n",
					rc);
			return rc;
		}
	}

	smbchg_charging_status_change(chip);

	vote(chip->usb_suspend_votable, USER_EN_VOTER, !chip->chg_enabled, 0);
@@ -6925,6 +6970,8 @@ static int smb_parse_dt(struct smbchg_chip *chip)
			"jeita-temp-hard-limit", rc, 1);
	OF_PROP_READ(chip, chip->aicl_rerun_period_s,
			"aicl-rerun-period-s", rc, 1);
	OF_PROP_READ(chip, chip->vchg_adc_channel,
			"vchg-adc-channel-id", rc, 1);

	/* read boolean configuration properties */
	chip->use_vfloat_adjustments = of_property_read_bool(node,
@@ -7480,7 +7527,7 @@ static int smbchg_probe(struct spmi_device *spmi)
	int rc;
	struct smbchg_chip *chip;
	struct power_supply *usb_psy;
	struct qpnp_vadc_chip *vadc_dev;
	struct qpnp_vadc_chip *vadc_dev, *vchg_vadc_dev;

	usb_psy = power_supply_get_by_name("usb");
	if (!usb_psy) {
@@ -7499,6 +7546,17 @@ static int smbchg_probe(struct spmi_device *spmi)
		}
	}

	if (of_find_property(spmi->dev.of_node, "qcom,vchg_sns-vadc", NULL)) {
		vchg_vadc_dev = qpnp_get_vadc(&spmi->dev, "vchg_sns");
		if (IS_ERR(vchg_vadc_dev)) {
			rc = PTR_ERR(vchg_vadc_dev);
			if (rc != -EPROBE_DEFER)
				dev_err(&spmi->dev, "Couldn't get vadc 'vchg' rc=%d\n",
						rc);
			return rc;
		}
	}

	chip = devm_kzalloc(&spmi->dev, sizeof(*chip), GFP_KERNEL);
	if (!chip) {
		dev_err(&spmi->dev, "Unable to allocate memory\n");
@@ -7557,6 +7615,7 @@ static int smbchg_probe(struct spmi_device *spmi)
	init_completion(&chip->usbin_uv_lowered);
	init_completion(&chip->usbin_uv_raised);
	chip->vadc_dev = vadc_dev;
	chip->vchg_vadc_dev = vchg_vadc_dev;
	chip->spmi = spmi;
	chip->dev = &spmi->dev;
	chip->usb_psy = usb_psy;