diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt index efd64cd90878..d239d4ef791c 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt @@ -281,6 +281,7 @@ Optional Properties: suspending USB path for fake battery. - qcom,vchg_sns-vadc Phandle of the VADC node. +- qcom,usbin-vadc Phandle of the VADC node. - qcom,vchg-adc-channel-id The ADC channel to which the VCHG is routed. Example: diff --git a/drivers/power/supply/qcom/qpnp-smbcharger.c b/drivers/power/supply/qcom/qpnp-smbcharger.c index a56854f6db6c..a43aae4b2d0f 100644 --- a/drivers/power/supply/qcom/qpnp-smbcharger.c +++ b/drivers/power/supply/qcom/qpnp-smbcharger.c @@ -277,6 +277,7 @@ struct smbchg_chip { bool skip_usb_notification; u32 vchg_adc_channel; struct qpnp_vadc_chip *vchg_vadc_dev; + struct qpnp_vadc_chip *vusb_vadc_dev; /* voters */ struct votable *fcc_votable; @@ -5744,6 +5745,30 @@ static void update_typec_otg_status(struct smbchg_chip *chip, int mode, } } +static int smbchg_get_vusb(struct smbchg_chip *chip) +{ + int rc; + struct qpnp_vadc_result adc_result; + + if (!is_usb_present(chip)) + return 0; + + if (chip->vusb_vadc_dev) { + rc = qpnp_vadc_read(chip->vusb_vadc_dev, + USBIN, &adc_result); + if (rc < 0) { + pr_smb(PR_STATUS, + "error in vusb_uv read rc = %d\n", rc); + return rc; + } + } else { + return -ENODATA; + } + pr_smb(PR_STATUS, "The value of vusb_uv %lld\n", adc_result.physical); + + return adc_result.physical; +} + static int smbchg_set_sdp_current(struct smbchg_chip *chip, int current_ma) { if (chip->usb_supply_type == POWER_SUPPLY_TYPE_USB) { @@ -5799,6 +5824,9 @@ static int smbchg_usb_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_HEALTH: val->intval = chip->usb_health; break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = smbchg_get_vusb(chip); + break; default: return -EINVAL; } @@ -5854,6 +5882,7 @@ static enum power_supply_property smbchg_usb_properties[] = { POWER_SUPPLY_PROP_REAL_TYPE, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, + POWER_SUPPLY_PROP_VOLTAGE_NOW, }; #define CHARGE_OUTPUT_VTG_RATIO 840 @@ -8201,6 +8230,7 @@ static int smbchg_probe(struct platform_device *pdev) struct smbchg_chip *chip; struct power_supply *typec_psy = NULL; struct qpnp_vadc_chip *vadc_dev = NULL, *vchg_vadc_dev = NULL; + struct qpnp_vadc_chip *vusb_vadc_dev = NULL; const char *typec_psy_name; struct power_supply_config usb_psy_cfg = {}; struct power_supply_config batt_psy_cfg = {}; @@ -8249,6 +8279,18 @@ static int smbchg_probe(struct platform_device *pdev) } } + vusb_vadc_dev = NULL; + if (of_find_property(pdev->dev.of_node, "qcom,usbin-vadc", NULL)) { + vusb_vadc_dev = qpnp_get_vadc(&pdev->dev, "usbin"); + if (IS_ERR(vusb_vadc_dev)) { + rc = PTR_ERR(vusb_vadc_dev); + if (rc != -EPROBE_DEFER) + dev_err(&pdev->dev, "Couldn't get vadc 'usbin' rc=%d\n", + rc); + return rc; + } + } + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (!chip) @@ -8354,6 +8396,7 @@ static int smbchg_probe(struct platform_device *pdev) init_completion(&chip->usbin_uv_raised); chip->vadc_dev = vadc_dev; chip->vchg_vadc_dev = vchg_vadc_dev; + chip->vusb_vadc_dev = vusb_vadc_dev; chip->pdev = pdev; chip->dev = &pdev->dev;