summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshay Jaiswal <ashayj@codeaurora.org>2016-12-07 19:39:38 +0530
committerAshay Jaiswal <ashayj@codeaurora.org>2016-12-20 17:23:42 +0530
commit7ac9349c5ad2616a07eb69b9ec8c75c13644eaaa (patch)
tree91926ddce292bed736b0e7a1ab8e0304a745aa70
parentc0a8f9e80a88354a7e2271a5cb61c61ac76a8818 (diff)
qcom-charger: smb2: support for micro USB mode
Add support to disable TypeC mode of charger hardware and enable micro USB mode. Enabling micro USB mode involves following changes: - hvdcp needs to be kept enabled. Create a new votable hvdcp_enable and vote true when uUSB connector is in use. - Add support of extcon for sending notification to USB driver. Change-Id: I109c07cd15052f4be15fee203f7cbaf02b6fd5cf Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt6
-rw-r--r--drivers/power/qcom-charger/qpnp-smb2.c187
-rw-r--r--drivers/power/qcom-charger/smb-lib.c129
-rw-r--r--drivers/power/qcom-charger/smb-lib.h16
-rw-r--r--drivers/power/qcom-charger/smb-reg.h4
5 files changed, 266 insertions, 76 deletions
diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt
index 94a1fdceec8f..cedb68820d26 100644
--- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt
+++ b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt
@@ -152,6 +152,12 @@ Charger specific properties:
be based off battery voltage. For both SOC and battery voltage,
charger receives the signal from FG to resume charging.
+- qcom,micro-usb
+ Usage: optional
+ Value type: <empty>
+ Definition: Boolean flag which indicates that the platform only support
+ micro usb port.
+
=============================================
Second Level Nodes - SMB2 Charger Peripherals
=============================================
diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c
index 543189ae5498..097e61097399 100644
--- a/drivers/power/qcom-charger/qpnp-smb2.c
+++ b/drivers/power/qcom-charger/qpnp-smb2.c
@@ -362,6 +362,9 @@ static int smb2_parse_dt(struct smb2 *chip)
chip->dt.auto_recharge_soc = of_property_read_bool(node,
"qcom,auto-recharge-soc");
+
+ chg->micro_usb_mode = of_property_read_bool(node, "qcom,micro-usb");
+
return 0;
}
@@ -429,16 +432,24 @@ static int smb2_usb_get_prop(struct power_supply *psy,
val->intval = chg->usb_psy_desc.type;
break;
case POWER_SUPPLY_PROP_TYPEC_MODE:
- if (chip->bad_part)
+ if (chg->micro_usb_mode)
+ val->intval = POWER_SUPPLY_TYPEC_NONE;
+ else if (chip->bad_part)
val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT;
else
rc = smblib_get_prop_typec_mode(chg, val);
break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
- rc = smblib_get_prop_typec_power_role(chg, val);
+ if (chg->micro_usb_mode)
+ val->intval = POWER_SUPPLY_TYPEC_PR_NONE;
+ else
+ rc = smblib_get_prop_typec_power_role(chg, val);
break;
case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION:
- rc = smblib_get_prop_typec_cc_orientation(chg, val);
+ if (chg->micro_usb_mode)
+ val->intval = 0;
+ else
+ rc = smblib_get_prop_typec_cc_orientation(chg, val);
break;
case POWER_SUPPLY_PROP_PD_ALLOWED:
rc = smblib_get_prop_pd_allowed(chg, val);
@@ -1070,6 +1081,99 @@ static int smb2_config_wipower_input_power(struct smb2 *chip, int uw)
return 0;
}
+static int smb2_configure_typec(struct smb_charger *chg)
+{
+ int rc;
+
+ /*
+ * trigger the usb-typec-change interrupt only when the CC state
+ * changes
+ */
+ rc = smblib_write(chg, TYPE_C_INTRPT_ENB_REG,
+ TYPEC_CCSTATE_CHANGE_INT_EN_BIT);
+ if (rc < 0) {
+ dev_err(chg->dev,
+ "Couldn't configure Type-C interrupts rc=%d\n", rc);
+ return rc;
+ }
+
+ /* configure power role for dual-role */
+ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ TYPEC_POWER_ROLE_CMD_MASK, 0);
+ if (rc < 0) {
+ dev_err(chg->dev,
+ "Couldn't configure power role for DRP rc=%d\n", rc);
+ return rc;
+ }
+
+ /*
+ * disable Type-C factory mode and stay in Attached.SRC state when VCONN
+ * over-current happens
+ */
+ rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
+ FACTORY_MODE_DETECTION_EN_BIT | VCONN_OC_CFG_BIT, 0);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't configure Type-C rc=%d\n", rc);
+ return rc;
+ }
+
+ /* increase VCONN softstart */
+ rc = smblib_masked_write(chg, TYPE_C_CFG_2_REG,
+ VCONN_SOFTSTART_CFG_MASK, VCONN_SOFTSTART_CFG_MASK);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't increase VCONN softstart rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ /* disable try.SINK mode */
+ rc = smblib_masked_write(chg, TYPE_C_CFG_3_REG, EN_TRYSINK_MODE_BIT, 0);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't set TRYSINK_MODE rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = smblib_validate_initial_typec_legacy_status(chg);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't validate typec legacy status rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ return rc;
+}
+
+static int smb2_disable_typec(struct smb_charger *chg)
+{
+ int rc;
+
+ /* configure FSM in idle state */
+ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ TYPEC_DISABLE_CMD_BIT, TYPEC_DISABLE_CMD_BIT);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't put FSM in idle rc=%d\n", rc);
+ return rc;
+ }
+
+ /* configure micro USB mode */
+ rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
+ TYPE_C_OR_U_USB_BIT, TYPE_C_OR_U_USB_BIT);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't enable micro USB mode rc=%d\n", rc);
+ return rc;
+ }
+
+ /* release FSM from idle state */
+ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ TYPEC_DISABLE_CMD_BIT, 0);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't release FSM rc=%d\n", rc);
+ return rc;
+ }
+
+ return rc;
+}
+
static int smb2_init_hw(struct smb2 *chip)
{
struct smb_charger *chg = &chip->chg;
@@ -1131,14 +1235,18 @@ static int smb2_init_hw(struct smb2 *chip)
DCP_VOTER, true, chip->dt.usb_icl_ua);
vote(chg->dc_icl_votable,
DEFAULT_VOTER, true, chip->dt.dc_icl_ua);
- vote(chg->hvdcp_disable_votable, DEFAULT_VOTER,
+ vote(chg->hvdcp_disable_votable_indirect, DEFAULT_VOTER,
chip->dt.hvdcp_disable, 0);
- vote(chg->hvdcp_disable_votable, PD_INACTIVE_VOTER,
+ vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER,
true, 0);
vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER,
true, 0);
vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER,
true, 0);
+ vote(chg->pd_disallowed_votable_indirect, MICRO_USB_VOTER,
+ chg->micro_usb_mode, 0);
+ vote(chg->hvdcp_enable_votable, MICRO_USB_VOTER,
+ chg->micro_usb_mode, 0);
/* Configure charge enable for software control; active high */
rc = smblib_masked_write(chg, CHGR_CFG2_REG,
@@ -1156,12 +1264,10 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
- /*
- * trigger the usb-typec-change interrupt only when the CC state
- * changes
- */
- rc = smblib_write(chg, TYPE_C_INTRPT_ENB_REG,
- TYPEC_CCSTATE_CHANGE_INT_EN_BIT);
+ if (chg->micro_usb_mode)
+ rc = smb2_disable_typec(chg);
+ else
+ rc = smb2_configure_typec(chg);
if (rc < 0) {
dev_err(chg->dev,
"Couldn't configure Type-C interrupts rc=%d\n", rc);
@@ -1186,42 +1292,6 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
- /* configure power role for dual-role */
- rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
- TYPEC_POWER_ROLE_CMD_MASK, 0);
- if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure power role for DRP rc=%d\n", rc);
- return rc;
- }
-
- /*
- * disable Type-C factory mode and stay in Attached.SRC state when VCONN
- * over-current happens
- */
- rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
- FACTORY_MODE_DETECTION_EN_BIT | VCONN_OC_CFG_BIT, 0);
- if (rc < 0) {
- dev_err(chg->dev, "Couldn't configure Type-C rc=%d\n", rc);
- return rc;
- }
-
- /* increase VCONN softstart */
- rc = smblib_masked_write(chg, TYPE_C_CFG_2_REG,
- VCONN_SOFTSTART_CFG_MASK, VCONN_SOFTSTART_CFG_MASK);
- if (rc < 0) {
- dev_err(chg->dev, "Couldn't increase VCONN softstart rc=%d\n",
- rc);
- return rc;
- }
-
- /* disable try.SINK mode */
- rc = smblib_masked_write(chg, TYPE_C_CFG_3_REG, EN_TRYSINK_MODE_BIT, 0);
- if (rc < 0) {
- dev_err(chg->dev, "Couldn't set TRYSINK_MODE rc=%d\n", rc);
- return rc;
- }
-
rc = smblib_masked_write(chg, QNOVO_PT_ENABLE_CMD_REG,
QNOVO_PT_ENABLE_CMD_BIT, QNOVO_PT_ENABLE_CMD_BIT);
if (rc < 0) {
@@ -1316,13 +1386,6 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
- rc = smblib_validate_initial_typec_legacy_status(chg);
- if (rc < 0) {
- dev_err(chg->dev, "Couldn't validate typec legacy status rc=%d\n",
- rc);
- return rc;
- }
-
if (chip->dt.auto_recharge_soc) {
rc = smblib_masked_write(chg, FG_UPDATE_CFG_2_SEL_REG,
SOC_LT_CHG_RECHARGE_THRESH_SEL_BIT |
@@ -1801,6 +1864,22 @@ static int smb2_probe(struct platform_device *pdev)
goto cleanup;
}
+ /* 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;
+ }
+
+ 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;
+ }
+
rc = smb2_init_dc_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize dc psy rc=%d\n", rc);
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index 9348091ec8dd..e6edc68bce18 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -486,10 +486,13 @@ static int try_rerun_apsd_for_hvdcp(struct smb_charger *chg)
* PD_INACTIVE_VOTER on hvdcp_disable_votable indicates whether
* apsd rerun was tried earlier
*/
- if (get_client_vote(chg->hvdcp_disable_votable, PD_INACTIVE_VOTER)) {
- vote(chg->hvdcp_disable_votable, PD_INACTIVE_VOTER, false, 0);
+ if (get_client_vote(chg->hvdcp_disable_votable_indirect,
+ PD_INACTIVE_VOTER)) {
+ vote(chg->hvdcp_disable_votable_indirect,
+ PD_INACTIVE_VOTER, false, 0);
/* ensure hvdcp is enabled */
- if (!get_effective_result(chg->hvdcp_disable_votable)) {
+ if (!get_effective_result(
+ chg->hvdcp_disable_votable_indirect)) {
apsd_result = smblib_get_apsd_result(chg);
if (apsd_result->bit & (QC_2P0_BIT | QC_3P0_BIT)) {
/* rerun APSD */
@@ -587,6 +590,40 @@ int smblib_mapping_cc_delta_from_field_value(struct smb_chg_param *param,
return 0;
}
+static void smblib_uusb_removal(struct smb_charger *chg)
+{
+ int rc;
+
+ /* reset both usbin current and voltage votes */
+ vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0);
+ vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0);
+ /* reset taper_end voter here */
+ vote(chg->pl_disable_votable, TAPER_END_VOTER, false, 0);
+
+ cancel_delayed_work_sync(&chg->hvdcp_detect_work);
+
+ /* reset AUTH_IRQ_EN_CFG_BIT */
+ rc = smblib_masked_write(chg, USBIN_SOURCE_CHANGE_INTRPT_ENB_REG,
+ AUTH_IRQ_EN_CFG_BIT, AUTH_IRQ_EN_CFG_BIT);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't enable QC auth setting rc=%d\n", rc);
+
+ /* reconfigure allowed voltage for HVDCP */
+ rc = smblib_write(chg, USBIN_ADAPTER_ALLOW_CFG_REG,
+ USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't set USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V rc=%d\n",
+ rc);
+
+ chg->voltage_min_uv = MICRO_5V;
+ chg->voltage_max_uv = MICRO_5V;
+
+ /* clear USB ICL vote for USB_PSY_VOTER */
+ rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't un-vote for USB ICL rc=%d\n", rc);
+}
+
/*********************
* VOTABLE CALLBACKS *
*********************/
@@ -898,9 +935,9 @@ static int smblib_pl_enable_indirect_vote_callback(struct votable *votable,
return 0;
}
-static int smblib_hvdcp_disable_vote_callback(struct votable *votable,
+static int smblib_hvdcp_enable_vote_callback(struct votable *votable,
void *data,
- int hvdcp_disable, const char *client)
+ int hvdcp_enable, const char *client)
{
struct smb_charger *chg = data;
int rc;
@@ -912,7 +949,7 @@ static int smblib_hvdcp_disable_vote_callback(struct votable *votable,
* This ensures only qc 2.0 detection runs but no vbus
* negotiation happens.
*/
- if (hvdcp_disable)
+ if (!hvdcp_enable)
val = HVDCP_EN_BIT;
rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
@@ -922,13 +959,24 @@ static int smblib_hvdcp_disable_vote_callback(struct votable *votable,
val);
if (rc < 0) {
smblib_err(chg, "Couldn't %s hvdcp rc=%d\n",
- hvdcp_disable ? "disable" : "enable", rc);
+ hvdcp_enable ? "enable" : "disable", rc);
return rc;
}
return 0;
}
+static int smblib_hvdcp_disable_indirect_vote_callback(struct votable *votable,
+ void *data, int hvdcp_disable, const char *client)
+{
+ struct smb_charger *chg = data;
+
+ vote(chg->hvdcp_enable_votable, HVDCP_INDIRECT_VOTER,
+ !hvdcp_disable, 0);
+
+ return 0;
+}
+
static int smblib_apsd_disable_vote_callback(struct votable *votable,
void *data,
int apsd_disable, const char *client)
@@ -2420,7 +2468,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
/* fetch the DPDM regulator */
if (!chg->dpdm_reg && of_get_property(chg->dev->of_node,
- "dpdm-supply", NULL)) {
+ "dpdm-supply", NULL)) {
chg->dpdm_reg = devm_regulator_get(chg->dev, "dpdm");
if (IS_ERR(chg->dpdm_reg)) {
smblib_err(chg, "Couldn't get dpdm regulator rc=%ld\n",
@@ -2449,11 +2497,17 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
smblib_err(chg, "Couldn't disable dpdm regulator rc=%d\n",
rc);
}
+
+ if (chg->micro_usb_mode) {
+ smblib_update_usb_type(chg);
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB, false);
+ smblib_uusb_removal(chg);
+ }
}
power_supply_changed(chg->usb_psy);
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s %s\n",
- irq_data->name, vbus_rising ? "attached" : "detached");
+ irq_data->name, vbus_rising ? "attached" : "detached");
return IRQ_HANDLED;
}
@@ -2633,6 +2687,9 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
switch (apsd_result->bit) {
case SDP_CHARGER_BIT:
case CDP_CHARGER_BIT:
+ if (chg->micro_usb_mode)
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB,
+ true);
case OCP_CHARGER_BIT:
case FLOAT_CHARGER_BIT:
/* if not DCP then no hvdcp timeout happens. Enable pd here */
@@ -2763,10 +2820,10 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
vote(chg->pd_disallowed_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0);
/* reset votes from vbus_cc_short */
- vote(chg->hvdcp_disable_votable, VBUS_CC_SHORT_VOTER, true, 0);
-
- vote(chg->hvdcp_disable_votable, PD_INACTIVE_VOTER, true, 0);
-
+ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
+ true, 0);
+ vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER,
+ true, 0);
/*
* cable could be removed during hard reset, remove its vote to
* disable apsd
@@ -2808,7 +2865,8 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg,
}
}
- vote(chg->hvdcp_disable_votable, VBUS_CC_SHORT_VOTER, vbus_cc_short, 0);
+ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
+ vbus_cc_short, 0);
vote(chg->pd_disallowed_votable_indirect, VBUS_CC_SHORT_VOTER,
vbus_cc_short, 0);
}
@@ -2851,6 +2909,26 @@ static void smblib_handle_typec_debounce_done(struct smb_charger *chg,
smblib_typec_mode_name[pval.intval]);
}
+irqreturn_t smblib_handle_usb_typec_change_for_uusb(struct smb_charger *chg)
+{
+ int rc;
+ u8 stat;
+
+ rc = smblib_read(chg, TYPE_C_STATUS_3_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read TYPE_C_STATUS_3 rc=%d\n", rc);
+ return IRQ_HANDLED;
+ }
+ smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_3 = 0x%02x OTG=%d\n",
+ stat, !!(stat & (U_USB_GND_NOVBUS_BIT | U_USB_GND_BIT)));
+
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB_HOST,
+ !!(stat & (U_USB_GND_NOVBUS_BIT | U_USB_GND_BIT)));
+ power_supply_changed(chg->usb_psy);
+
+ return IRQ_HANDLED;
+}
+
irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
{
struct smb_irq_data *irq_data = data;
@@ -2859,6 +2937,9 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
u8 stat4, stat5;
bool debounce_done, sink_attached, legacy_cable;
+ if (chg->micro_usb_mode)
+ return smblib_handle_usb_typec_change_for_uusb(chg);
+
/* WA - not when PD hard_reset WIP on cc2 in sink mode */
if (chg->cc2_sink_detach_flag == CC2_SINK_STD)
return IRQ_HANDLED;
@@ -2884,7 +2965,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
if (stat4 & TYPEC_VBUS_ERROR_STATUS_BIT)
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s vbus-error\n",
- irq_data->name);
+ irq_data->name);
power_supply_changed(chg->usb_psy);
smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n", stat4);
@@ -3234,12 +3315,22 @@ static int smblib_create_votables(struct smb_charger *chg)
return rc;
}
- chg->hvdcp_disable_votable = create_votable("HVDCP_DISABLE",
+ chg->hvdcp_disable_votable_indirect = create_votable(
+ "HVDCP_DISABLE_INDIRECT",
+ VOTE_SET_ANY,
+ smblib_hvdcp_disable_indirect_vote_callback,
+ chg);
+ if (IS_ERR(chg->hvdcp_disable_votable_indirect)) {
+ rc = PTR_ERR(chg->hvdcp_disable_votable_indirect);
+ return rc;
+ }
+
+ chg->hvdcp_enable_votable = create_votable("HVDCP_ENABLE",
VOTE_SET_ANY,
- smblib_hvdcp_disable_vote_callback,
+ smblib_hvdcp_enable_vote_callback,
chg);
- if (IS_ERR(chg->hvdcp_disable_votable)) {
- rc = PTR_ERR(chg->hvdcp_disable_votable);
+ if (IS_ERR(chg->hvdcp_enable_votable)) {
+ rc = PTR_ERR(chg->hvdcp_enable_votable);
return rc;
}
diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h
index 089c6a6fe1b2..af2805cbb712 100644
--- a/drivers/power/qcom-charger/smb-lib.h
+++ b/drivers/power/qcom-charger/smb-lib.h
@@ -16,6 +16,7 @@
#include <linux/irqreturn.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/consumer.h>
+#include <linux/extcon.h>
#include "storm-watch.h"
enum print_reason {
@@ -48,6 +49,8 @@ enum print_reason {
#define LEGACY_CABLE_VOTER "LEGACY_CABLE_VOTER"
#define PD_INACTIVE_VOTER "PD_INACTIVE_VOTER"
#define BOOST_BACK_VOTER "BOOST_BACK_VOTER"
+#define HVDCP_INDIRECT_VOTER "HVDCP_INDIRECT_VOTER"
+#define MICRO_USB_VOTER "MICRO_USB_VOTER"
enum smb_mode {
PARALLEL_MASTER = 0,
@@ -68,6 +71,12 @@ enum {
TYPEC_CC2_REMOVAL_WA_BIT = BIT(2),
};
+static const unsigned int smblib_extcon_cable[] = {
+ EXTCON_USB,
+ EXTCON_USB_HOST,
+ EXTCON_NONE,
+};
+
struct smb_regulator {
struct regulator_dev *rdev;
struct regulator_desc rdesc;
@@ -181,7 +190,8 @@ struct smb_charger {
struct votable *pl_disable_votable;
struct votable *chg_disable_votable;
struct votable *pl_enable_votable_indirect;
- struct votable *hvdcp_disable_votable;
+ struct votable *hvdcp_disable_votable_indirect;
+ struct votable *hvdcp_enable_votable;
struct votable *apsd_disable_votable;
/* work */
@@ -213,12 +223,16 @@ struct smb_charger {
bool step_chg_enabled;
bool is_hdc;
bool chg_done;
+ bool micro_usb_mode;
int input_limited_fcc_ua;
/* workaround flag */
u32 wa_flags;
enum cc2_sink_type cc2_sink_detach_flag;
int boost_current_ua;
+
+ /* extcon for VBUS / ID notification to USB for uUSB */
+ struct extcon_dev *extcon;
};
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/qcom-charger/smb-reg.h
index d9d12c9d7cf6..a30efbe3651e 100644
--- a/drivers/power/qcom-charger/smb-reg.h
+++ b/drivers/power/qcom-charger/smb-reg.h
@@ -494,9 +494,9 @@ enum {
#define TYPE_C_STATUS_3_REG (USBIN_BASE + 0x0D)
#define ENABLE_BANDGAP_BIT BIT(7)
-#define U_USB_GROUND_NOVBUS_BIT BIT(6)
+#define U_USB_GND_NOVBUS_BIT BIT(6)
#define U_USB_FLOAT_NOVBUS_BIT BIT(5)
-#define U_USB_GROUND_BIT BIT(4)
+#define U_USB_GND_BIT BIT(4)
#define U_USB_FMB1_BIT BIT(3)
#define U_USB_FLOAT1_BIT BIT(2)
#define U_USB_FMB2_BIT BIT(1)