Loading Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt +7 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,13 @@ Charger specific properties: Definition: Boolean flag which indicates that the charger should not draw current from any of its input sources (USB, DC). - qcom,use-extcon Usage: optional Value type: <empty> Definition: Boolean flag which specify that smb138x will act as main charger to do extcon USB calls. If not defined, other charger driver can act as main charger to do extcon USB calls. - qcom,fcc-max-ua Usage: optional Value type: <u32> Loading drivers/power/supply/qcom/smb-lib.c +45 −0 Original line number Diff line number Diff line Loading @@ -3642,6 +3642,37 @@ static void smblib_force_legacy_icl(struct smb_charger *chg, int pst) } } static void smblib_notify_extcon_props(struct smb_charger *chg, int id) { union extcon_property_value val; union power_supply_propval prop_val; smblib_get_prop_typec_cc_orientation(chg, &prop_val); val.intval = ((prop_val.intval == 2) ? 1 : 0); extcon_set_property(chg->extcon, id, EXTCON_PROP_USB_TYPEC_POLARITY, val); val.intval = true; extcon_set_property(chg->extcon, id, EXTCON_PROP_USB_SS, val); } static void smblib_notify_device_mode(struct smb_charger *chg, bool enable) { if (enable) smblib_notify_extcon_props(chg, EXTCON_USB); extcon_set_state_sync(chg->extcon, EXTCON_USB, enable); } static void smblib_notify_usb_host(struct smb_charger *chg, bool enable) { if (enable) smblib_notify_extcon_props(chg, EXTCON_USB_HOST); extcon_set_state_sync(chg->extcon, EXTCON_USB_HOST, enable); } #define HVDCP_DET_MS 2500 static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) { Loading @@ -3664,6 +3695,8 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) /* if not DCP then no hvdcp timeout happens. Enable pd here */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); if (chg->use_extcon) smblib_notify_device_mode(chg, true); break; case OCP_CHARGER_BIT: case FLOAT_CHARGER_BIT: Loading Loading @@ -3749,6 +3782,10 @@ static void typec_sink_insertion(struct smb_charger *chg) */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); if (chg->use_extcon) { smblib_notify_usb_host(chg, true); chg->otg_present = true; } } static void typec_sink_removal(struct smb_charger *chg) Loading Loading @@ -3899,6 +3936,14 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) typec_sink_removal(chg); smblib_update_usb_type(chg); if (chg->use_extcon) { if (chg->otg_present) smblib_notify_usb_host(chg, false); else smblib_notify_device_mode(chg, false); } chg->otg_present = false; } static void smblib_handle_typec_insertion(struct smb_charger *chg) Loading drivers/power/supply/qcom/smb-lib.h +5 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,9 @@ static const unsigned int smblib_extcon_cable[] = { EXTCON_NONE, }; /* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */ static const u32 smblib_extcon_exclusive[] = {0x3, 0}; struct smb_regulator { struct regulator_dev *rdev; struct regulator_desc rdesc; Loading Loading @@ -331,6 +334,8 @@ struct smb_charger { int usb_icl_change_irq_enabled; u32 jeita_status; u8 float_cfg; bool use_extcon; bool otg_present; /* workaround flag */ u32 wa_flags; Loading drivers/power/supply/qcom/smb138x-charger.c +51 −8 Original line number Diff line number Diff line Loading @@ -170,6 +170,9 @@ static int smb138x_parse_dt(struct smb138x *chip) chip->dt.suspend_input = of_property_read_bool(node, "qcom,suspend-input"); chg->use_extcon = of_property_read_bool(node, "qcom,use-extcon"); rc = of_property_read_u32(node, "qcom,fcc-max-ua", &chip->dt.fcc_ua); if (rc < 0) Loading Loading @@ -1405,55 +1408,95 @@ static int smb138x_master_probe(struct smb138x *chip) rc = smb138x_parse_dt(chip); if (rc < 0) { pr_err("Couldn't parse device tree rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_vbus_regulator(chip); if (rc < 0) { pr_err("Couldn't initialize vbus regulator rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_vconn_regulator(chip); if (rc < 0) { pr_err("Couldn't initialize vconn regulator rc=%d\n", rc); return rc; goto cleanup; } if (chg->use_extcon) { /* extcon registration */ chg->extcon = devm_extcon_dev_allocate(chg->dev, smblib_extcon_cable); if (IS_ERR(chg->extcon)) { rc = PTR_ERR(chg->extcon); dev_err(chg->dev, "failed to allocate extcon device rc=%d\n", rc); goto cleanup; } chg->extcon->mutually_exclusive = smblib_extcon_exclusive; rc = devm_extcon_dev_register(chg->dev, chg->extcon); if (rc < 0) { dev_err(chg->dev, "failed to register extcon device rc=%d\n", rc); goto cleanup; } /* Support reporting polarity and speed via properties */ rc = extcon_set_property_capability(chg->extcon, EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY); rc |= extcon_set_property_capability(chg->extcon, EXTCON_USB, EXTCON_PROP_USB_SS); rc |= extcon_set_property_capability(chg->extcon, EXTCON_USB_HOST, EXTCON_PROP_USB_TYPEC_POLARITY); rc |= extcon_set_property_capability(chg->extcon, EXTCON_USB_HOST, EXTCON_PROP_USB_SS); if (rc < 0) { dev_err(chg->dev, "failed to configure extcon capabilities\n"); goto cleanup; } } rc = smb138x_init_usb_psy(chip); if (rc < 0) { pr_err("Couldn't initialize usb psy rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_batt_psy(chip); if (rc < 0) { pr_err("Couldn't initialize batt psy rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_hw(chip); if (rc < 0) { pr_err("Couldn't initialize hardware rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_determine_initial_status(chip); if (rc < 0) { pr_err("Couldn't determine initial status rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_request_interrupts(chip); if (rc < 0) { pr_err("Couldn't request interrupts rc=%d\n", rc); return rc; goto cleanup; } return rc; cleanup: smblib_deinit(chg); return rc; } static int smb138x_slave_probe(struct smb138x *chip) Loading Loading
Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt +7 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,13 @@ Charger specific properties: Definition: Boolean flag which indicates that the charger should not draw current from any of its input sources (USB, DC). - qcom,use-extcon Usage: optional Value type: <empty> Definition: Boolean flag which specify that smb138x will act as main charger to do extcon USB calls. If not defined, other charger driver can act as main charger to do extcon USB calls. - qcom,fcc-max-ua Usage: optional Value type: <u32> Loading
drivers/power/supply/qcom/smb-lib.c +45 −0 Original line number Diff line number Diff line Loading @@ -3642,6 +3642,37 @@ static void smblib_force_legacy_icl(struct smb_charger *chg, int pst) } } static void smblib_notify_extcon_props(struct smb_charger *chg, int id) { union extcon_property_value val; union power_supply_propval prop_val; smblib_get_prop_typec_cc_orientation(chg, &prop_val); val.intval = ((prop_val.intval == 2) ? 1 : 0); extcon_set_property(chg->extcon, id, EXTCON_PROP_USB_TYPEC_POLARITY, val); val.intval = true; extcon_set_property(chg->extcon, id, EXTCON_PROP_USB_SS, val); } static void smblib_notify_device_mode(struct smb_charger *chg, bool enable) { if (enable) smblib_notify_extcon_props(chg, EXTCON_USB); extcon_set_state_sync(chg->extcon, EXTCON_USB, enable); } static void smblib_notify_usb_host(struct smb_charger *chg, bool enable) { if (enable) smblib_notify_extcon_props(chg, EXTCON_USB_HOST); extcon_set_state_sync(chg->extcon, EXTCON_USB_HOST, enable); } #define HVDCP_DET_MS 2500 static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) { Loading @@ -3664,6 +3695,8 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) /* if not DCP then no hvdcp timeout happens. Enable pd here */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); if (chg->use_extcon) smblib_notify_device_mode(chg, true); break; case OCP_CHARGER_BIT: case FLOAT_CHARGER_BIT: Loading Loading @@ -3749,6 +3782,10 @@ static void typec_sink_insertion(struct smb_charger *chg) */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); if (chg->use_extcon) { smblib_notify_usb_host(chg, true); chg->otg_present = true; } } static void typec_sink_removal(struct smb_charger *chg) Loading Loading @@ -3899,6 +3936,14 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) typec_sink_removal(chg); smblib_update_usb_type(chg); if (chg->use_extcon) { if (chg->otg_present) smblib_notify_usb_host(chg, false); else smblib_notify_device_mode(chg, false); } chg->otg_present = false; } static void smblib_handle_typec_insertion(struct smb_charger *chg) Loading
drivers/power/supply/qcom/smb-lib.h +5 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,9 @@ static const unsigned int smblib_extcon_cable[] = { EXTCON_NONE, }; /* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */ static const u32 smblib_extcon_exclusive[] = {0x3, 0}; struct smb_regulator { struct regulator_dev *rdev; struct regulator_desc rdesc; Loading Loading @@ -331,6 +334,8 @@ struct smb_charger { int usb_icl_change_irq_enabled; u32 jeita_status; u8 float_cfg; bool use_extcon; bool otg_present; /* workaround flag */ u32 wa_flags; Loading
drivers/power/supply/qcom/smb138x-charger.c +51 −8 Original line number Diff line number Diff line Loading @@ -170,6 +170,9 @@ static int smb138x_parse_dt(struct smb138x *chip) chip->dt.suspend_input = of_property_read_bool(node, "qcom,suspend-input"); chg->use_extcon = of_property_read_bool(node, "qcom,use-extcon"); rc = of_property_read_u32(node, "qcom,fcc-max-ua", &chip->dt.fcc_ua); if (rc < 0) Loading Loading @@ -1405,55 +1408,95 @@ static int smb138x_master_probe(struct smb138x *chip) rc = smb138x_parse_dt(chip); if (rc < 0) { pr_err("Couldn't parse device tree rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_vbus_regulator(chip); if (rc < 0) { pr_err("Couldn't initialize vbus regulator rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_vconn_regulator(chip); if (rc < 0) { pr_err("Couldn't initialize vconn regulator rc=%d\n", rc); return rc; goto cleanup; } if (chg->use_extcon) { /* extcon registration */ chg->extcon = devm_extcon_dev_allocate(chg->dev, smblib_extcon_cable); if (IS_ERR(chg->extcon)) { rc = PTR_ERR(chg->extcon); dev_err(chg->dev, "failed to allocate extcon device rc=%d\n", rc); goto cleanup; } chg->extcon->mutually_exclusive = smblib_extcon_exclusive; rc = devm_extcon_dev_register(chg->dev, chg->extcon); if (rc < 0) { dev_err(chg->dev, "failed to register extcon device rc=%d\n", rc); goto cleanup; } /* Support reporting polarity and speed via properties */ rc = extcon_set_property_capability(chg->extcon, EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY); rc |= extcon_set_property_capability(chg->extcon, EXTCON_USB, EXTCON_PROP_USB_SS); rc |= extcon_set_property_capability(chg->extcon, EXTCON_USB_HOST, EXTCON_PROP_USB_TYPEC_POLARITY); rc |= extcon_set_property_capability(chg->extcon, EXTCON_USB_HOST, EXTCON_PROP_USB_SS); if (rc < 0) { dev_err(chg->dev, "failed to configure extcon capabilities\n"); goto cleanup; } } rc = smb138x_init_usb_psy(chip); if (rc < 0) { pr_err("Couldn't initialize usb psy rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_batt_psy(chip); if (rc < 0) { pr_err("Couldn't initialize batt psy rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_init_hw(chip); if (rc < 0) { pr_err("Couldn't initialize hardware rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_determine_initial_status(chip); if (rc < 0) { pr_err("Couldn't determine initial status rc=%d\n", rc); return rc; goto cleanup; } rc = smb138x_request_interrupts(chip); if (rc < 0) { pr_err("Couldn't request interrupts rc=%d\n", rc); return rc; goto cleanup; } return rc; cleanup: smblib_deinit(chg); return rc; } static int smb138x_slave_probe(struct smb138x *chip) Loading