From 716a46317a4f11c07f6b3cb64cf8860e52fcfc36 Mon Sep 17 00:00:00 2001 From: Kavya Nunna Date: Tue, 21 May 2019 10:32:25 +0530 Subject: [PATCH 1/2] power: qpnp-smbcharger: Add support for float charger detection PMI8996 charger does not detect FLOAT adapter. To support it, FLOAT detection is done by the USB driver and notified to PMIC by reporting -ETIMEDOUT through the CURRENT_MAX power-supply property. Charger then configures the charge current to 1500mA. Change-Id: I6abd4668b41988d98465f00402aa2be558054cdd Signed-off-by: Kavya Nunna --- drivers/power/supply/qcom/qpnp-smbcharger.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smbcharger.c b/drivers/power/supply/qcom/qpnp-smbcharger.c index 6abe0e021877..a56854f6db6c 100644 --- a/drivers/power/supply/qcom/qpnp-smbcharger.c +++ b/drivers/power/supply/qcom/qpnp-smbcharger.c @@ -5747,6 +5747,16 @@ static void update_typec_otg_status(struct smbchg_chip *chip, int mode, static int smbchg_set_sdp_current(struct smbchg_chip *chip, int current_ma) { if (chip->usb_supply_type == POWER_SUPPLY_TYPE_USB) { + if (current_ma == -ETIMEDOUT) { + /* float charger */ + current_ma = CURRENT_1500_MA; + pr_smb(PR_MISC, + "Update usb_type to FLOAT current=%dmA\n", + current_ma); + chip->usb_psy_d.type = POWER_SUPPLY_TYPE_USB_FLOAT; + } else { + current_ma = current_ma / 1000; + } /* Override if type-c charger used */ if (chip->typec_current_ma > 500 && current_ma < chip->typec_current_ma) { @@ -5807,7 +5817,7 @@ static int smbchg_usb_set_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: - smbchg_set_sdp_current(chip, val->intval / 1000); + smbchg_set_sdp_current(chip, val->intval); default: return -EINVAL; } From 726ccfec942d6110bf26896e5bfa57f7f83aa54f Mon Sep 17 00:00:00 2001 From: Kavya Nunna Date: Mon, 20 May 2019 11:42:22 +0530 Subject: [PATCH 2/2] power: qpnp-smbcharger: Add voltage now property in usb psy Add VOLTAGE_NOW power supply property to expose the USB voltage. Change-Id: I3041aafaf365c205e53451a5d4ee79dcfe6b78bf Signed-off-by: Kavya Nunna --- .../power/supply/qcom/qpnp-smbcharger.txt | 1 + drivers/power/supply/qcom/qpnp-smbcharger.c | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) 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;