Loading Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt +17 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,13 @@ Charger specific properties: Definition: Should specify the phandle of PMI's revid module. This is used to identify the PMI subtype. - io-channels - io-channel-names Usage: optional Value type: <phandle> Definition: For details about IIO bindings see: Documentation/devicetree/bindings/iio/iio-bindings.txt - qcom,batteryless-platform Usage: optional Value type: <empty> Loading Loading @@ -223,13 +230,22 @@ Peripheral specific properties: Example ======= pmi8998_charger: qcom,qpnp-smb5 { pm855b_charger: qcom,qpnp-smb5 { compatible = "qcom,qpnp-smb5"; #address-cells = <1>; #size-cells = <1>; qcom,pmic-revid = <&pm855b_revid>; dpdm-supply = <&qusb_phy0>; io-channels = <&pm855b_vadc ADC_USB_IN_V_16>, <&pm855b_vadc ADC_USB_IN_I>, <&pm855b_vadc ADC_CHG_TEMP>; io-channel-names = "usb_in_voltage", "usb_in_current", "chg_temp"; qcom,chgr@1000 { reg = <0x1000 0x100>; interrupts = <0x2 0x10 0x0 IRQ_TYPE_NONE>, Loading drivers/power/supply/qcom/qpnp-smb5.c +64 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/regulator/driver.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/machine.h> #include <linux/iio/consumer.h> #include <linux/pmic-voter.h> #include "smb5-reg.h" #include "smb5-lib.h" Loading Loading @@ -377,6 +378,50 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) chg->otg_delay_ms = OTG_DEFAULT_DEGLITCH_TIME_MS; rc = of_property_match_string(node, "io-channel-names", "usb_in_voltage"); if (rc >= 0) { chg->iio.usbin_v_chan = iio_channel_get(chg->dev, "usb_in_voltage"); if (IS_ERR(chg->iio.usbin_v_chan)) { rc = PTR_ERR(chg->iio.usbin_v_chan); if (rc != -EPROBE_DEFER) dev_err(chg->dev, "USBIN_V channel unavailable, %ld\n", rc); chg->iio.usbin_v_chan = NULL; return rc; } } rc = of_property_match_string(node, "io-channel-names", "chg_temp"); if (rc >= 0) { chg->iio.temp_chan = iio_channel_get(chg->dev, "chg_temp"); if (IS_ERR(chg->iio.temp_chan)) { rc = PTR_ERR(chg->iio.temp_chan); if (rc != -EPROBE_DEFER) dev_err(chg->dev, "CHG_TEMP channel unavailable, %ld\n", rc); chg->iio.temp_chan = NULL; return rc; } } rc = of_property_match_string(node, "io-channel-names", "usb_in_current"); if (rc >= 0) { chg->iio.usbin_i_chan = iio_channel_get(chg->dev, "usb_in_current"); if (IS_ERR(chg->iio.usbin_i_chan)) { rc = PTR_ERR(chg->iio.usbin_i_chan); if (rc != -EPROBE_DEFER) dev_err(chg->dev, "USBIN_I channel unavailable, %ld\n", rc); chg->iio.usbin_i_chan = NULL; return rc; } } return 0; } Loading @@ -386,6 +431,7 @@ static int smb5_parse_dt(struct smb5 *chip) static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_PD_CURRENT_MAX, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_TYPE, Loading Loading @@ -440,6 +486,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX: rc = smblib_get_prop_usb_voltage_max(chg, val); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: rc = smblib_get_prop_usb_voltage_now(chg, val); break; case POWER_SUPPLY_PROP_PD_CURRENT_MAX: val->intval = get_client_vote(chg->usb_icl_votable, PD_VOTER); break; Loading Loading @@ -476,6 +525,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: rc = smblib_get_prop_input_current_settled(chg, val); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW: rc = smblib_get_prop_usb_current_now(chg, val); break; case POWER_SUPPLY_PROP_BOOST_CURRENT: val->intval = chg->boost_current_ua; break; Loading Loading @@ -961,6 +1013,7 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CHARGER_TEMP, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_MAX, Loading @@ -987,6 +1040,8 @@ static int smb5_batt_get_prop(struct power_supply *psy, union power_supply_propval *val) { struct smb_charger *chg = power_supply_get_drvdata(psy); union power_supply_propval pval = {0, }; int rc = 0; switch (psp) { Loading Loading @@ -1014,6 +1069,15 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: rc = smblib_get_prop_system_temp_level_max(chg, val); break; case POWER_SUPPLY_PROP_CHARGER_TEMP: rc = smblib_get_prop_usb_present(chg, &pval); if (rc < 0) { pr_err("Couldn't get usb present rc=%d\n", rc); break; } if (pval.intval) rc = smblib_get_prop_charger_temp(chg, val); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: rc = smblib_get_prop_input_current_limited(chg, val); break; Loading drivers/power/supply/qcom/smb5-lib.c +73 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/regulator/driver.h> #include <linux/qpnp/qpnp-revid.h> #include <linux/irq.h> #include <linux/iio/consumer.h> #include <linux/pmic-voter.h> #include "smb5-lib.h" #include "smb5-reg.h" Loading Loading @@ -1799,6 +1800,36 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, return 0; } int smblib_get_prop_usb_voltage_now(struct smb_charger *chg, union power_supply_propval *val) { if (chg->iio.usbin_v_chan) return iio_read_channel_processed(chg->iio.usbin_v_chan, &val->intval); else return -ENODATA; } int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val) { int rc; if (chg->iio.temp_chan) { rc = iio_read_channel_processed(chg->iio.temp_chan, &val->intval); if (rc < 0) { pr_err("Error in reading temp channel, rc=%d", rc); return rc; } val->intval /= 100; } else { return -ENODATA; } return rc; } int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg, union power_supply_propval *val) { Loading Loading @@ -1947,6 +1978,36 @@ int smblib_get_prop_typec_power_role(struct smb_charger *chg, return rc; } int smblib_get_prop_usb_current_now(struct smb_charger *chg, union power_supply_propval *val) { int rc = 0; if (chg->iio.usbin_i_chan) { rc = iio_read_channel_processed(chg->iio.usbin_i_chan, &val->intval); /* * For PM855B, scaling factor = reciprocal of * 0.2V/A in Buck mode, 0.4V/A in Boost mode. */ if (smblib_get_prop_ufp_mode(chg) != POWER_SUPPLY_TYPEC_NONE) { val->intval *= 5; return rc; } if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE) { val->intval = DIV_ROUND_CLOSEST(val->intval * 100, 40); return rc; } } else { rc = -ENODATA; } val->intval = 0; return rc; } int smblib_get_prop_input_current_settled(struct smb_charger *chg, union power_supply_propval *val) { Loading Loading @@ -3575,6 +3636,16 @@ static void smblib_destroy_votables(struct smb_charger *chg) destroy_votable(chg->chg_disable_votable); } static void smblib_iio_deinit(struct smb_charger *chg) { if (!IS_ERR_OR_NULL(chg->iio.usbin_v_chan)) iio_channel_release(chg->iio.usbin_v_chan); if (!IS_ERR_OR_NULL(chg->iio.usbin_i_chan)) iio_channel_release(chg->iio.usbin_i_chan); if (!IS_ERR_OR_NULL(chg->iio.temp_chan)) iio_channel_release(chg->iio.temp_chan); } int smblib_init(struct smb_charger *chg) { int rc = 0; Loading Loading @@ -3666,5 +3737,7 @@ int smblib_deinit(struct smb_charger *chg) return -EINVAL; } smblib_iio_deinit(chg); return 0; } drivers/power/supply/qcom/smb5-lib.h +6 −4 Original line number Diff line number Diff line Loading @@ -246,14 +246,10 @@ struct parallel_params { struct smb_iio { struct iio_channel *temp_chan; struct iio_channel *temp_max_chan; struct iio_channel *usbin_i_chan; struct iio_channel *usbin_v_chan; struct iio_channel *batt_i_chan; struct iio_channel *connector_temp_chan; struct iio_channel *connector_temp_thr1_chan; struct iio_channel *connector_temp_thr2_chan; struct iio_channel *connector_temp_thr3_chan; }; struct smb_charger { Loading Loading @@ -486,6 +482,10 @@ int smblib_get_prop_usb_suspend(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_usb_voltage_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_usb_current_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_typec_power_role(struct smb_charger *chg, Loading @@ -498,6 +498,8 @@ int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_pe_start(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_die_health(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pd_current_max(struct smb_charger *chg, Loading Loading
Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt +17 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,13 @@ Charger specific properties: Definition: Should specify the phandle of PMI's revid module. This is used to identify the PMI subtype. - io-channels - io-channel-names Usage: optional Value type: <phandle> Definition: For details about IIO bindings see: Documentation/devicetree/bindings/iio/iio-bindings.txt - qcom,batteryless-platform Usage: optional Value type: <empty> Loading Loading @@ -223,13 +230,22 @@ Peripheral specific properties: Example ======= pmi8998_charger: qcom,qpnp-smb5 { pm855b_charger: qcom,qpnp-smb5 { compatible = "qcom,qpnp-smb5"; #address-cells = <1>; #size-cells = <1>; qcom,pmic-revid = <&pm855b_revid>; dpdm-supply = <&qusb_phy0>; io-channels = <&pm855b_vadc ADC_USB_IN_V_16>, <&pm855b_vadc ADC_USB_IN_I>, <&pm855b_vadc ADC_CHG_TEMP>; io-channel-names = "usb_in_voltage", "usb_in_current", "chg_temp"; qcom,chgr@1000 { reg = <0x1000 0x100>; interrupts = <0x2 0x10 0x0 IRQ_TYPE_NONE>, Loading
drivers/power/supply/qcom/qpnp-smb5.c +64 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/regulator/driver.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/machine.h> #include <linux/iio/consumer.h> #include <linux/pmic-voter.h> #include "smb5-reg.h" #include "smb5-lib.h" Loading Loading @@ -377,6 +378,50 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) chg->otg_delay_ms = OTG_DEFAULT_DEGLITCH_TIME_MS; rc = of_property_match_string(node, "io-channel-names", "usb_in_voltage"); if (rc >= 0) { chg->iio.usbin_v_chan = iio_channel_get(chg->dev, "usb_in_voltage"); if (IS_ERR(chg->iio.usbin_v_chan)) { rc = PTR_ERR(chg->iio.usbin_v_chan); if (rc != -EPROBE_DEFER) dev_err(chg->dev, "USBIN_V channel unavailable, %ld\n", rc); chg->iio.usbin_v_chan = NULL; return rc; } } rc = of_property_match_string(node, "io-channel-names", "chg_temp"); if (rc >= 0) { chg->iio.temp_chan = iio_channel_get(chg->dev, "chg_temp"); if (IS_ERR(chg->iio.temp_chan)) { rc = PTR_ERR(chg->iio.temp_chan); if (rc != -EPROBE_DEFER) dev_err(chg->dev, "CHG_TEMP channel unavailable, %ld\n", rc); chg->iio.temp_chan = NULL; return rc; } } rc = of_property_match_string(node, "io-channel-names", "usb_in_current"); if (rc >= 0) { chg->iio.usbin_i_chan = iio_channel_get(chg->dev, "usb_in_current"); if (IS_ERR(chg->iio.usbin_i_chan)) { rc = PTR_ERR(chg->iio.usbin_i_chan); if (rc != -EPROBE_DEFER) dev_err(chg->dev, "USBIN_I channel unavailable, %ld\n", rc); chg->iio.usbin_i_chan = NULL; return rc; } } return 0; } Loading @@ -386,6 +431,7 @@ static int smb5_parse_dt(struct smb5 *chip) static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_PD_CURRENT_MAX, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_TYPE, Loading Loading @@ -440,6 +486,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX: rc = smblib_get_prop_usb_voltage_max(chg, val); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: rc = smblib_get_prop_usb_voltage_now(chg, val); break; case POWER_SUPPLY_PROP_PD_CURRENT_MAX: val->intval = get_client_vote(chg->usb_icl_votable, PD_VOTER); break; Loading Loading @@ -476,6 +525,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: rc = smblib_get_prop_input_current_settled(chg, val); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW: rc = smblib_get_prop_usb_current_now(chg, val); break; case POWER_SUPPLY_PROP_BOOST_CURRENT: val->intval = chg->boost_current_ua; break; Loading Loading @@ -961,6 +1013,7 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CHARGER_TEMP, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_MAX, Loading @@ -987,6 +1040,8 @@ static int smb5_batt_get_prop(struct power_supply *psy, union power_supply_propval *val) { struct smb_charger *chg = power_supply_get_drvdata(psy); union power_supply_propval pval = {0, }; int rc = 0; switch (psp) { Loading Loading @@ -1014,6 +1069,15 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: rc = smblib_get_prop_system_temp_level_max(chg, val); break; case POWER_SUPPLY_PROP_CHARGER_TEMP: rc = smblib_get_prop_usb_present(chg, &pval); if (rc < 0) { pr_err("Couldn't get usb present rc=%d\n", rc); break; } if (pval.intval) rc = smblib_get_prop_charger_temp(chg, val); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: rc = smblib_get_prop_input_current_limited(chg, val); break; Loading
drivers/power/supply/qcom/smb5-lib.c +73 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/regulator/driver.h> #include <linux/qpnp/qpnp-revid.h> #include <linux/irq.h> #include <linux/iio/consumer.h> #include <linux/pmic-voter.h> #include "smb5-lib.h" #include "smb5-reg.h" Loading Loading @@ -1799,6 +1800,36 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, return 0; } int smblib_get_prop_usb_voltage_now(struct smb_charger *chg, union power_supply_propval *val) { if (chg->iio.usbin_v_chan) return iio_read_channel_processed(chg->iio.usbin_v_chan, &val->intval); else return -ENODATA; } int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val) { int rc; if (chg->iio.temp_chan) { rc = iio_read_channel_processed(chg->iio.temp_chan, &val->intval); if (rc < 0) { pr_err("Error in reading temp channel, rc=%d", rc); return rc; } val->intval /= 100; } else { return -ENODATA; } return rc; } int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg, union power_supply_propval *val) { Loading Loading @@ -1947,6 +1978,36 @@ int smblib_get_prop_typec_power_role(struct smb_charger *chg, return rc; } int smblib_get_prop_usb_current_now(struct smb_charger *chg, union power_supply_propval *val) { int rc = 0; if (chg->iio.usbin_i_chan) { rc = iio_read_channel_processed(chg->iio.usbin_i_chan, &val->intval); /* * For PM855B, scaling factor = reciprocal of * 0.2V/A in Buck mode, 0.4V/A in Boost mode. */ if (smblib_get_prop_ufp_mode(chg) != POWER_SUPPLY_TYPEC_NONE) { val->intval *= 5; return rc; } if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE) { val->intval = DIV_ROUND_CLOSEST(val->intval * 100, 40); return rc; } } else { rc = -ENODATA; } val->intval = 0; return rc; } int smblib_get_prop_input_current_settled(struct smb_charger *chg, union power_supply_propval *val) { Loading Loading @@ -3575,6 +3636,16 @@ static void smblib_destroy_votables(struct smb_charger *chg) destroy_votable(chg->chg_disable_votable); } static void smblib_iio_deinit(struct smb_charger *chg) { if (!IS_ERR_OR_NULL(chg->iio.usbin_v_chan)) iio_channel_release(chg->iio.usbin_v_chan); if (!IS_ERR_OR_NULL(chg->iio.usbin_i_chan)) iio_channel_release(chg->iio.usbin_i_chan); if (!IS_ERR_OR_NULL(chg->iio.temp_chan)) iio_channel_release(chg->iio.temp_chan); } int smblib_init(struct smb_charger *chg) { int rc = 0; Loading Loading @@ -3666,5 +3737,7 @@ int smblib_deinit(struct smb_charger *chg) return -EINVAL; } smblib_iio_deinit(chg); return 0; }
drivers/power/supply/qcom/smb5-lib.h +6 −4 Original line number Diff line number Diff line Loading @@ -246,14 +246,10 @@ struct parallel_params { struct smb_iio { struct iio_channel *temp_chan; struct iio_channel *temp_max_chan; struct iio_channel *usbin_i_chan; struct iio_channel *usbin_v_chan; struct iio_channel *batt_i_chan; struct iio_channel *connector_temp_chan; struct iio_channel *connector_temp_thr1_chan; struct iio_channel *connector_temp_thr2_chan; struct iio_channel *connector_temp_thr3_chan; }; struct smb_charger { Loading Loading @@ -486,6 +482,10 @@ int smblib_get_prop_usb_suspend(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_usb_voltage_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_usb_current_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_typec_power_role(struct smb_charger *chg, Loading @@ -498,6 +498,8 @@ int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_pe_start(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_die_health(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pd_current_max(struct smb_charger *chg, Loading