Loading Documentation/devicetree/bindings/power/qpnp-linear-charger.txt +4 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,10 @@ Parent node optional properties: BPD and disables BTC. Declare this node only if you are using an external charger and not the PMIC internal LBC. - qcom,chgr-led-support There is a current sink device in linear charger module, it is used to control a led which can act as a charger led as well as a general notification led. Sub node required structure: - A qcom,charger node must be a child of an SPMI node that has specified Loading drivers/power/qpnp-linear-charger.c +80 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/qpnp/qpnp-adc.h> #include <linux/alarmtimer.h> #include <linux/bitops.h> #include <linux/leds.h> #define CREATE_MASK(NUM_BITS, POS) \ ((unsigned char) (((1 << (NUM_BITS)) - 1) << (POS))) Loading Loading @@ -267,6 +268,7 @@ struct vddtrim_map vddtrim_map[] = { * @cfg_charger_detect_eoc: charger can detect end of charging * @cfg_disable_vbatdet_based_recharge: keep VBATDET comparator overriden to * low and VBATDET irq disabled. * @cfg_chgr_led_support: support charger led work. * @cfg_safe_current: battery safety current setting * @cfg_hot_batt_p: hot battery threshold setting * @cfg_cold_batt_p: eold battery threshold setting Loading Loading @@ -317,6 +319,7 @@ struct qpnp_lbc_chip { bool cfg_use_fake_battery; bool fastchg_on; bool cfg_use_external_charger; bool cfg_chgr_led_support; unsigned int cfg_warm_bat_chg_ma; unsigned int cfg_cool_bat_chg_ma; unsigned int cfg_safe_voltage_mv; Loading Loading @@ -361,6 +364,7 @@ struct qpnp_lbc_chip { struct qpnp_adc_tm_btm_param adc_param; struct qpnp_vadc_chip *vadc_dev; struct qpnp_adc_tm_chip *adc_tm_dev; struct led_classdev led_cdev; }; static void qpnp_lbc_enable_irq(struct qpnp_lbc_chip *chip, Loading Loading @@ -971,6 +975,68 @@ static int qpnp_lbc_tchg_max_set(struct qpnp_lbc_chip *chip, int minutes) return rc; } #define LBC_CHGR_LED 0x4D #define CHGR_LED_ON BIT(0) #define CHGR_LED_OFF 0x0 #define CHGR_LED_STAT_MASK LBC_MASK(1, 0) static void qpnp_lbc_chgr_led_brightness_set(struct led_classdev *cdev, enum led_brightness value) { struct qpnp_lbc_chip *chip = container_of(cdev, struct qpnp_lbc_chip, led_cdev); u8 reg; int rc; if (value > LED_FULL) value = LED_FULL; pr_debug("set the charger led brightness to value=%d\n", value); reg = (value > LED_OFF) ? CHGR_LED_ON : CHGR_LED_OFF; rc = qpnp_lbc_masked_write(chip, chip->chgr_base + LBC_CHGR_LED, CHGR_LED_STAT_MASK, reg); if (rc) pr_err("Failed to write charger led rc=%d\n", rc); } static enum led_brightness qpnp_lbc_chgr_led_brightness_get(struct led_classdev *cdev) { struct qpnp_lbc_chip *chip = container_of(cdev, struct qpnp_lbc_chip, led_cdev); u8 reg_val, chgr_led_sts; int rc; rc = qpnp_lbc_read(chip, chip->chgr_base + LBC_CHGR_LED, ®_val, 1); if (rc) { pr_err("Failed to read charger led rc=%d\n", rc); return rc; } chgr_led_sts = reg_val & CHGR_LED_STAT_MASK; pr_debug("charger led brightness chgr_led_sts=%d\n", chgr_led_sts); return (chgr_led_sts == CHGR_LED_ON) ? LED_FULL : LED_OFF; } static int qpnp_lbc_register_chgr_led(struct qpnp_lbc_chip *chip) { int rc; chip->led_cdev.name = "red"; chip->led_cdev.brightness_set = qpnp_lbc_chgr_led_brightness_set; chip->led_cdev.brightness_get = qpnp_lbc_chgr_led_brightness_get; rc = led_classdev_register(chip->dev, &chip->led_cdev); if (rc) dev_err(chip->dev, "unable to register charger led, rc=%d\n", rc); return rc; }; static int qpnp_lbc_vbatdet_override(struct qpnp_lbc_chip *chip, int ovr_val) { int rc; Loading Loading @@ -1941,6 +2007,12 @@ static int qpnp_charger_read_dt_props(struct qpnp_lbc_chip *chip) chip->cfg_disable_vbatdet_based_recharge = of_property_read_bool(chip->spmi->dev.of_node, "qcom,disable-vbatdet-based-recharge"); /* Get the charger led support property */ chip->cfg_chgr_led_support = of_property_read_bool(chip->spmi->dev.of_node, "qcom,chgr-led-support"); /* Disable charging when faking battery values */ if (chip->cfg_use_fake_battery) chip->cfg_charging_disabled = true; Loading Loading @@ -2563,6 +2635,14 @@ static int qpnp_lbc_probe(struct spmi_device *spmi) return rc; } if (chip->cfg_chgr_led_support) { rc = qpnp_lbc_register_chgr_led(chip); if (rc) { pr_err("unable to register charger led rc=%d\n", rc); return rc; } } if (chip->bat_if_base) { chip->batt_present = qpnp_lbc_is_batt_present(chip); chip->batt_psy.name = "battery"; Loading Loading
Documentation/devicetree/bindings/power/qpnp-linear-charger.txt +4 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,10 @@ Parent node optional properties: BPD and disables BTC. Declare this node only if you are using an external charger and not the PMIC internal LBC. - qcom,chgr-led-support There is a current sink device in linear charger module, it is used to control a led which can act as a charger led as well as a general notification led. Sub node required structure: - A qcom,charger node must be a child of an SPMI node that has specified Loading
drivers/power/qpnp-linear-charger.c +80 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/qpnp/qpnp-adc.h> #include <linux/alarmtimer.h> #include <linux/bitops.h> #include <linux/leds.h> #define CREATE_MASK(NUM_BITS, POS) \ ((unsigned char) (((1 << (NUM_BITS)) - 1) << (POS))) Loading Loading @@ -267,6 +268,7 @@ struct vddtrim_map vddtrim_map[] = { * @cfg_charger_detect_eoc: charger can detect end of charging * @cfg_disable_vbatdet_based_recharge: keep VBATDET comparator overriden to * low and VBATDET irq disabled. * @cfg_chgr_led_support: support charger led work. * @cfg_safe_current: battery safety current setting * @cfg_hot_batt_p: hot battery threshold setting * @cfg_cold_batt_p: eold battery threshold setting Loading Loading @@ -317,6 +319,7 @@ struct qpnp_lbc_chip { bool cfg_use_fake_battery; bool fastchg_on; bool cfg_use_external_charger; bool cfg_chgr_led_support; unsigned int cfg_warm_bat_chg_ma; unsigned int cfg_cool_bat_chg_ma; unsigned int cfg_safe_voltage_mv; Loading Loading @@ -361,6 +364,7 @@ struct qpnp_lbc_chip { struct qpnp_adc_tm_btm_param adc_param; struct qpnp_vadc_chip *vadc_dev; struct qpnp_adc_tm_chip *adc_tm_dev; struct led_classdev led_cdev; }; static void qpnp_lbc_enable_irq(struct qpnp_lbc_chip *chip, Loading Loading @@ -971,6 +975,68 @@ static int qpnp_lbc_tchg_max_set(struct qpnp_lbc_chip *chip, int minutes) return rc; } #define LBC_CHGR_LED 0x4D #define CHGR_LED_ON BIT(0) #define CHGR_LED_OFF 0x0 #define CHGR_LED_STAT_MASK LBC_MASK(1, 0) static void qpnp_lbc_chgr_led_brightness_set(struct led_classdev *cdev, enum led_brightness value) { struct qpnp_lbc_chip *chip = container_of(cdev, struct qpnp_lbc_chip, led_cdev); u8 reg; int rc; if (value > LED_FULL) value = LED_FULL; pr_debug("set the charger led brightness to value=%d\n", value); reg = (value > LED_OFF) ? CHGR_LED_ON : CHGR_LED_OFF; rc = qpnp_lbc_masked_write(chip, chip->chgr_base + LBC_CHGR_LED, CHGR_LED_STAT_MASK, reg); if (rc) pr_err("Failed to write charger led rc=%d\n", rc); } static enum led_brightness qpnp_lbc_chgr_led_brightness_get(struct led_classdev *cdev) { struct qpnp_lbc_chip *chip = container_of(cdev, struct qpnp_lbc_chip, led_cdev); u8 reg_val, chgr_led_sts; int rc; rc = qpnp_lbc_read(chip, chip->chgr_base + LBC_CHGR_LED, ®_val, 1); if (rc) { pr_err("Failed to read charger led rc=%d\n", rc); return rc; } chgr_led_sts = reg_val & CHGR_LED_STAT_MASK; pr_debug("charger led brightness chgr_led_sts=%d\n", chgr_led_sts); return (chgr_led_sts == CHGR_LED_ON) ? LED_FULL : LED_OFF; } static int qpnp_lbc_register_chgr_led(struct qpnp_lbc_chip *chip) { int rc; chip->led_cdev.name = "red"; chip->led_cdev.brightness_set = qpnp_lbc_chgr_led_brightness_set; chip->led_cdev.brightness_get = qpnp_lbc_chgr_led_brightness_get; rc = led_classdev_register(chip->dev, &chip->led_cdev); if (rc) dev_err(chip->dev, "unable to register charger led, rc=%d\n", rc); return rc; }; static int qpnp_lbc_vbatdet_override(struct qpnp_lbc_chip *chip, int ovr_val) { int rc; Loading Loading @@ -1941,6 +2007,12 @@ static int qpnp_charger_read_dt_props(struct qpnp_lbc_chip *chip) chip->cfg_disable_vbatdet_based_recharge = of_property_read_bool(chip->spmi->dev.of_node, "qcom,disable-vbatdet-based-recharge"); /* Get the charger led support property */ chip->cfg_chgr_led_support = of_property_read_bool(chip->spmi->dev.of_node, "qcom,chgr-led-support"); /* Disable charging when faking battery values */ if (chip->cfg_use_fake_battery) chip->cfg_charging_disabled = true; Loading Loading @@ -2563,6 +2635,14 @@ static int qpnp_lbc_probe(struct spmi_device *spmi) return rc; } if (chip->cfg_chgr_led_support) { rc = qpnp_lbc_register_chgr_led(chip); if (rc) { pr_err("unable to register charger led rc=%d\n", rc); return rc; } } if (chip->bat_if_base) { chip->batt_present = qpnp_lbc_is_batt_present(chip); chip->batt_psy.name = "battery"; Loading