Loading Documentation/devicetree/bindings/power/smb1360-charger-fg.txt +18 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,21 @@ Optional Properties: - qcom,rsense-10mhom A bool property to indicate the Rsense resistor configuraton. If set, the Rsense is 10mOhm else its 20mOhm. - qcom,otg-fet-present A bool property to indicate that a pMOS FET is present to boost the OTG current. On enabling this the max OTG current supported is 3x(qcom,otg-batt-curr-limit). - qcom,otg-fet-enable-gpio GPIO for enabling and disabling OTG FET. Following should be the PMIC gpio configuration: { qcom,mode = <1>; //Digital output qcom,pull = <0>; //Pull up configuration qcom,vin-sel = <0>; //Voltage level: VPH_PWR qcom,src-sel = <0>; //Pin function: GPIO qcom,master-en = <1>; //Enable } Please go through the documentation for PMIC gpio configuration details: Documentation/devicetree/bindings/gpio/qpnp-pin.txt Example: i2c@f9967000 { Loading Loading @@ -189,5 +204,8 @@ Example: qcom,otg-batt-curr-limit = <950>; qcom,fg-reset-at-pon; qcom,otg-fet-present; qcom,otg-fet-enable-gpio = <&pm8916_gpios 3 0>; }; }; drivers/power/smb1360-charger-fg.c +156 −40 Original line number Diff line number Diff line Loading @@ -330,6 +330,9 @@ struct smb1360_chip { int fg_reset_threshold_mv; bool fg_reset_at_pon; bool rsense_10mohm; bool otg_fet_present; bool fet_gain_enabled; int otg_fet_enable_gpio; /* status tracking */ bool usb_present; Loading Loading @@ -1796,15 +1799,18 @@ static int smb1360_adjust_current_gain(struct smb1360_chip *chip, {0xF1, 0x00}, }; if (gain_factor) { rc = smb1360_fg_read(chip, CURRENT_GAIN_LSB_REG, ®[0]); if (rc) { pr_err("Unable to set FG access I2C address rc=%d\n", rc); pr_err("Unable to set FG access I2C address rc=%d\n", rc); return rc; } rc = smb1360_fg_read(chip, CURRENT_GAIN_MSB_REG, ®[1]); if (rc) { pr_err("Unable to set FG access I2C address rc=%d\n", rc); pr_err("Unable to set FG access I2C address rc=%d\n", rc); return rc; } Loading @@ -1823,8 +1829,8 @@ static int smb1360_adjust_current_gain(struct smb1360_chip *chip, if (reg_val_mapping[i][0] == 0xE3) reg_val_mapping[i][1] = reg[1]; pr_debug("Writing reg_add=%x value=%x\n", reg_val_mapping[i][0], reg_val_mapping[i][1]); pr_debug("Writing reg_add=%x value=%x\n", reg_val_mapping[i][0], reg_val_mapping[i][1]); rc = smb1360_fg_write(chip, reg_val_mapping[i][0], reg_val_mapping[i][1]); Loading @@ -1834,6 +1840,15 @@ static int smb1360_adjust_current_gain(struct smb1360_chip *chip, return rc; } } } else { pr_debug("Disabling gain correction\n"); rc = smb1360_fg_write(chip, 0xF0, 0x00); if (rc) { pr_err("Write fg address 0x%x failed, rc = %d\n", 0xF0, rc); return rc; } } return 0; } Loading Loading @@ -1878,6 +1893,54 @@ restore_fg: return rc; } static int smb1360_otg_disable(struct smb1360_chip *chip) { int rc; rc = smb1360_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, 0); if (rc) { pr_err("Couldn't disable OTG mode rc=%d\n", rc); return rc; } /* Disable current gain configuration */ if (chip->otg_fet_present && chip->fet_gain_enabled) { /* Disable FET */ gpio_set_value(chip->otg_fet_enable_gpio, 1); rc = smb1360_otp_gain_config(chip, 0); if (rc < 0) pr_err("Couldn't config OTP gain config rc=%d\n", rc); else chip->fet_gain_enabled = false; } return rc; } static int otg_fail_handler(struct smb1360_chip *chip, u8 rt_stat) { int rc; pr_debug("OTG Failed stat=%d\n", rt_stat); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); return 0; } static int otg_oc_handler(struct smb1360_chip *chip, u8 rt_stat) { int rc; pr_debug("OTG over-current stat=%d\n", rt_stat); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); return 0; } struct smb_irq_info { const char *name; int (*smb_irq)(struct smb1360_chip *chip, Loading Loading @@ -1996,9 +2059,11 @@ static struct irq_handler_info handlers[] = { }, { .name = "otg_fail", .smb_irq = otg_fail_handler, }, { .name = "otg_oc", .smb_irq = otg_oc_handler, }, }, }, Loading Loading @@ -2607,8 +2672,22 @@ static int smb1360_otg_regulator_enable(struct regulator_dev *rdev) rc = smb1360_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, CMD_OTG_EN_BIT); if (rc) if (rc) { pr_err("Couldn't enable OTG mode rc=%d\n", rc); return rc; } pr_debug("OTG mode enabled\n"); /* Enable current gain configuration */ if (chip->otg_fet_present) { /* Enable FET */ gpio_set_value(chip->otg_fet_enable_gpio, 0); rc = smb1360_otp_gain_config(chip, 3); if (rc < 0) pr_err("Couldn't config OTP gain config rc=%d\n", rc); else chip->fet_gain_enabled = true; } return rc; } Loading @@ -2618,10 +2697,11 @@ static int smb1360_otg_regulator_disable(struct regulator_dev *rdev) int rc = 0; struct smb1360_chip *chip = rdev_get_drvdata(rdev); rc = smb1360_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, 0); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); pr_err("Couldn't disable OTG regulator rc=%d\n", rc); pr_debug("OTG mode disabled\n"); return rc; } Loading Loading @@ -3344,6 +3424,25 @@ static int smb1360_hw_init(struct smb1360_chip *chip) } } if (chip->otg_fet_present) { /* Configure OTG FET control gpio */ rc = devm_gpio_request_one(chip->dev, chip->otg_fet_enable_gpio, GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH, "smb1360_otg_fet_gpio"); if (rc) { pr_err("Unable to request gpio rc=%d\n", rc); return rc; } /* Reset current gain to the default value */ rc = smb1360_otp_gain_config(chip, 0); if (rc < 0) { pr_err("Couldn't config OTP gain rc=%d\n", rc); return rc; } } rc = smb1360_check_batt_profile(chip); if (rc) pr_err("Unable to modify battery profile\n"); Loading Loading @@ -3805,6 +3904,19 @@ static int smb_parse_dt(struct smb1360_chip *chip) } } chip->otg_fet_present = of_property_read_bool(node, "qcom,otg-fet-present"); if (chip->otg_fet_present) { chip->otg_fet_enable_gpio = of_get_named_gpio(node, "qcom,otg-fet-enable-gpio", 0); if (!gpio_is_valid(chip->otg_fet_enable_gpio)) { if (chip->otg_fet_enable_gpio != -EPROBE_DEFER) pr_err("Unable to get OTG FET enable gpio=%d\n", chip->otg_fet_enable_gpio); return chip->otg_fet_enable_gpio; } } chip->pulsed_irq = of_property_read_bool(node, "qcom,stat-pulsed-irq"); rc = of_property_read_u32(node, "qcom,float-voltage-mv", Loading Loading @@ -4021,13 +4133,6 @@ static int smb1360_probe(struct i2c_client *client, pr_debug("default_i2c_addr=%x\n", chip->default_i2c_addr); rc = smb1360_regulator_init(chip); if (rc) { dev_err(&client->dev, "Couldn't initialize smb349 ragulator rc=%d\n", rc); return rc; } rc = smb1360_hw_init(chip); if (rc < 0) { dev_err(&client->dev, Loading @@ -4035,6 +4140,13 @@ static int smb1360_probe(struct i2c_client *client, goto fail_hw_init; } rc = smb1360_regulator_init(chip); if (rc) { dev_err(&client->dev, "Couldn't initialize smb349 ragulator rc=%d\n", rc); return rc; } rc = determine_initial_status(chip); if (rc < 0) { dev_err(&client->dev, Loading Loading @@ -4303,6 +4415,10 @@ static void smb1360_shutdown(struct i2c_client *client) int rc; struct smb1360_chip *chip = i2c_get_clientdata(client); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); if (chip->shdn_after_pwroff) { rc = smb1360_poweroff(chip); if (rc) Loading Loading
Documentation/devicetree/bindings/power/smb1360-charger-fg.txt +18 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,21 @@ Optional Properties: - qcom,rsense-10mhom A bool property to indicate the Rsense resistor configuraton. If set, the Rsense is 10mOhm else its 20mOhm. - qcom,otg-fet-present A bool property to indicate that a pMOS FET is present to boost the OTG current. On enabling this the max OTG current supported is 3x(qcom,otg-batt-curr-limit). - qcom,otg-fet-enable-gpio GPIO for enabling and disabling OTG FET. Following should be the PMIC gpio configuration: { qcom,mode = <1>; //Digital output qcom,pull = <0>; //Pull up configuration qcom,vin-sel = <0>; //Voltage level: VPH_PWR qcom,src-sel = <0>; //Pin function: GPIO qcom,master-en = <1>; //Enable } Please go through the documentation for PMIC gpio configuration details: Documentation/devicetree/bindings/gpio/qpnp-pin.txt Example: i2c@f9967000 { Loading Loading @@ -189,5 +204,8 @@ Example: qcom,otg-batt-curr-limit = <950>; qcom,fg-reset-at-pon; qcom,otg-fet-present; qcom,otg-fet-enable-gpio = <&pm8916_gpios 3 0>; }; };
drivers/power/smb1360-charger-fg.c +156 −40 Original line number Diff line number Diff line Loading @@ -330,6 +330,9 @@ struct smb1360_chip { int fg_reset_threshold_mv; bool fg_reset_at_pon; bool rsense_10mohm; bool otg_fet_present; bool fet_gain_enabled; int otg_fet_enable_gpio; /* status tracking */ bool usb_present; Loading Loading @@ -1796,15 +1799,18 @@ static int smb1360_adjust_current_gain(struct smb1360_chip *chip, {0xF1, 0x00}, }; if (gain_factor) { rc = smb1360_fg_read(chip, CURRENT_GAIN_LSB_REG, ®[0]); if (rc) { pr_err("Unable to set FG access I2C address rc=%d\n", rc); pr_err("Unable to set FG access I2C address rc=%d\n", rc); return rc; } rc = smb1360_fg_read(chip, CURRENT_GAIN_MSB_REG, ®[1]); if (rc) { pr_err("Unable to set FG access I2C address rc=%d\n", rc); pr_err("Unable to set FG access I2C address rc=%d\n", rc); return rc; } Loading @@ -1823,8 +1829,8 @@ static int smb1360_adjust_current_gain(struct smb1360_chip *chip, if (reg_val_mapping[i][0] == 0xE3) reg_val_mapping[i][1] = reg[1]; pr_debug("Writing reg_add=%x value=%x\n", reg_val_mapping[i][0], reg_val_mapping[i][1]); pr_debug("Writing reg_add=%x value=%x\n", reg_val_mapping[i][0], reg_val_mapping[i][1]); rc = smb1360_fg_write(chip, reg_val_mapping[i][0], reg_val_mapping[i][1]); Loading @@ -1834,6 +1840,15 @@ static int smb1360_adjust_current_gain(struct smb1360_chip *chip, return rc; } } } else { pr_debug("Disabling gain correction\n"); rc = smb1360_fg_write(chip, 0xF0, 0x00); if (rc) { pr_err("Write fg address 0x%x failed, rc = %d\n", 0xF0, rc); return rc; } } return 0; } Loading Loading @@ -1878,6 +1893,54 @@ restore_fg: return rc; } static int smb1360_otg_disable(struct smb1360_chip *chip) { int rc; rc = smb1360_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, 0); if (rc) { pr_err("Couldn't disable OTG mode rc=%d\n", rc); return rc; } /* Disable current gain configuration */ if (chip->otg_fet_present && chip->fet_gain_enabled) { /* Disable FET */ gpio_set_value(chip->otg_fet_enable_gpio, 1); rc = smb1360_otp_gain_config(chip, 0); if (rc < 0) pr_err("Couldn't config OTP gain config rc=%d\n", rc); else chip->fet_gain_enabled = false; } return rc; } static int otg_fail_handler(struct smb1360_chip *chip, u8 rt_stat) { int rc; pr_debug("OTG Failed stat=%d\n", rt_stat); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); return 0; } static int otg_oc_handler(struct smb1360_chip *chip, u8 rt_stat) { int rc; pr_debug("OTG over-current stat=%d\n", rt_stat); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); return 0; } struct smb_irq_info { const char *name; int (*smb_irq)(struct smb1360_chip *chip, Loading Loading @@ -1996,9 +2059,11 @@ static struct irq_handler_info handlers[] = { }, { .name = "otg_fail", .smb_irq = otg_fail_handler, }, { .name = "otg_oc", .smb_irq = otg_oc_handler, }, }, }, Loading Loading @@ -2607,8 +2672,22 @@ static int smb1360_otg_regulator_enable(struct regulator_dev *rdev) rc = smb1360_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, CMD_OTG_EN_BIT); if (rc) if (rc) { pr_err("Couldn't enable OTG mode rc=%d\n", rc); return rc; } pr_debug("OTG mode enabled\n"); /* Enable current gain configuration */ if (chip->otg_fet_present) { /* Enable FET */ gpio_set_value(chip->otg_fet_enable_gpio, 0); rc = smb1360_otp_gain_config(chip, 3); if (rc < 0) pr_err("Couldn't config OTP gain config rc=%d\n", rc); else chip->fet_gain_enabled = true; } return rc; } Loading @@ -2618,10 +2697,11 @@ static int smb1360_otg_regulator_disable(struct regulator_dev *rdev) int rc = 0; struct smb1360_chip *chip = rdev_get_drvdata(rdev); rc = smb1360_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, 0); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); pr_err("Couldn't disable OTG regulator rc=%d\n", rc); pr_debug("OTG mode disabled\n"); return rc; } Loading Loading @@ -3344,6 +3424,25 @@ static int smb1360_hw_init(struct smb1360_chip *chip) } } if (chip->otg_fet_present) { /* Configure OTG FET control gpio */ rc = devm_gpio_request_one(chip->dev, chip->otg_fet_enable_gpio, GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH, "smb1360_otg_fet_gpio"); if (rc) { pr_err("Unable to request gpio rc=%d\n", rc); return rc; } /* Reset current gain to the default value */ rc = smb1360_otp_gain_config(chip, 0); if (rc < 0) { pr_err("Couldn't config OTP gain rc=%d\n", rc); return rc; } } rc = smb1360_check_batt_profile(chip); if (rc) pr_err("Unable to modify battery profile\n"); Loading Loading @@ -3805,6 +3904,19 @@ static int smb_parse_dt(struct smb1360_chip *chip) } } chip->otg_fet_present = of_property_read_bool(node, "qcom,otg-fet-present"); if (chip->otg_fet_present) { chip->otg_fet_enable_gpio = of_get_named_gpio(node, "qcom,otg-fet-enable-gpio", 0); if (!gpio_is_valid(chip->otg_fet_enable_gpio)) { if (chip->otg_fet_enable_gpio != -EPROBE_DEFER) pr_err("Unable to get OTG FET enable gpio=%d\n", chip->otg_fet_enable_gpio); return chip->otg_fet_enable_gpio; } } chip->pulsed_irq = of_property_read_bool(node, "qcom,stat-pulsed-irq"); rc = of_property_read_u32(node, "qcom,float-voltage-mv", Loading Loading @@ -4021,13 +4133,6 @@ static int smb1360_probe(struct i2c_client *client, pr_debug("default_i2c_addr=%x\n", chip->default_i2c_addr); rc = smb1360_regulator_init(chip); if (rc) { dev_err(&client->dev, "Couldn't initialize smb349 ragulator rc=%d\n", rc); return rc; } rc = smb1360_hw_init(chip); if (rc < 0) { dev_err(&client->dev, Loading @@ -4035,6 +4140,13 @@ static int smb1360_probe(struct i2c_client *client, goto fail_hw_init; } rc = smb1360_regulator_init(chip); if (rc) { dev_err(&client->dev, "Couldn't initialize smb349 ragulator rc=%d\n", rc); return rc; } rc = determine_initial_status(chip); if (rc < 0) { dev_err(&client->dev, Loading Loading @@ -4303,6 +4415,10 @@ static void smb1360_shutdown(struct i2c_client *client) int rc; struct smb1360_chip *chip = i2c_get_clientdata(client); rc = smb1360_otg_disable(chip); if (rc) pr_err("Couldn't disable OTG mode rc=%d\n", rc); if (chip->shdn_after_pwroff) { rc = smb1360_poweroff(chip); if (rc) Loading