summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt6
-rw-r--r--drivers/power/supply/qcom/qpnp-smb2.c11
-rw-r--r--drivers/power/supply/qcom/smb-lib.c52
-rw-r--r--drivers/power/supply/qcom/smb-lib.h3
4 files changed, 49 insertions, 23 deletions
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
index 894c34553a22..b41219d51973 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
@@ -181,6 +181,12 @@ Charger specific properties:
Definition: Specifies the maximum charger buck/boost switching frequency in
KHz. It overrides the max frequency defined for the charger.
+- qcom,otg-deglitch-time-ms
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies the deglitch interval for OTG detection.
+ If the value is not present, 50 msec is used as default.
+
=============================================
Second Level Nodes - SMB2 Charger Peripherals
=============================================
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index 94b9e9c4d912..b2597987292b 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -266,8 +266,9 @@ module_param_named(
debug_mask, __debug_mask, int, S_IRUSR | S_IWUSR
);
-#define MICRO_1P5A 1500000
-#define MICRO_P1A 100000
+#define MICRO_1P5A 1500000
+#define MICRO_P1A 100000
+#define OTG_DEFAULT_DEGLITCH_TIME_MS 50
static int smb2_parse_dt(struct smb2 *chip)
{
struct smb_charger *chg = &chip->chg;
@@ -400,6 +401,12 @@ static int smb2_parse_dt(struct smb2 *chip)
chg->suspend_input_on_debug_batt = of_property_read_bool(node,
"qcom,suspend-input-on-debug-batt");
+
+ rc = of_property_read_u32(node, "qcom,otg-deglitch-time-ms",
+ &chg->otg_delay_ms);
+ if (rc < 0)
+ chg->otg_delay_ms = OTG_DEFAULT_DEGLITCH_TIME_MS;
+
return 0;
}
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index a191391a3904..cc50e0f478d1 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -3750,26 +3750,6 @@ 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;
-}
-
static void smblib_usb_typec_change(struct smb_charger *chg)
{
int rc;
@@ -3804,7 +3784,11 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
struct smb_charger *chg = irq_data->parent_data;
if (chg->micro_usb_mode) {
- smblib_handle_usb_typec_change_for_uusb(chg);
+ cancel_delayed_work_sync(&chg->uusb_otg_work);
+ vote(chg->awake_votable, OTG_DELAY_VOTER, true, 0);
+ smblib_dbg(chg, PR_INTERRUPT, "Scheduling OTG work\n");
+ schedule_delayed_work(&chg->uusb_otg_work,
+ msecs_to_jiffies(chg->otg_delay_ms));
return IRQ_HANDLED;
}
@@ -3889,6 +3873,30 @@ irqreturn_t smblib_handle_wdog_bark(int irq, void *data)
/***************
* Work Queues *
***************/
+static void smblib_uusb_otg_work(struct work_struct *work)
+{
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ uusb_otg_work.work);
+ int rc;
+ u8 stat;
+ bool otg;
+
+ 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);
+ goto out;
+ }
+
+ otg = !!(stat & (U_USB_GND_NOVBUS_BIT | U_USB_GND_BIT));
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB_HOST, otg);
+ smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_3 = 0x%02x OTG=%d\n",
+ stat, otg);
+ power_supply_changed(chg->usb_psy);
+
+out:
+ vote(chg->awake_votable, OTG_DELAY_VOTER, false, 0);
+}
+
static void smblib_hvdcp_detect_work(struct work_struct *work)
{
@@ -4482,6 +4490,7 @@ int smblib_init(struct smb_charger *chg)
INIT_DELAYED_WORK(&chg->icl_change_work, smblib_icl_change_work);
INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work);
INIT_WORK(&chg->legacy_detection_work, smblib_legacy_detection_work);
+ INIT_DELAYED_WORK(&chg->uusb_otg_work, smblib_uusb_otg_work);
chg->fake_capacity = -EINVAL;
chg->fake_input_current_limited = -EINVAL;
@@ -4536,6 +4545,7 @@ int smblib_deinit(struct smb_charger *chg)
cancel_delayed_work_sync(&chg->icl_change_work);
cancel_delayed_work_sync(&chg->pl_enable_work);
cancel_work_sync(&chg->legacy_detection_work);
+ cancel_delayed_work_sync(&chg->uusb_otg_work);
power_supply_unreg_notifier(&chg->nb);
smblib_destroy_votables(chg);
qcom_batt_deinit();
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 5dc60ecb9436..3fedff8897ee 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -64,6 +64,7 @@ enum print_reason {
#define CC2_WA_VOTER "CC2_WA_VOTER"
#define QNOVO_VOTER "QNOVO_VOTER"
#define BATT_PROFILE_VOTER "BATT_PROFILE_VOTER"
+#define OTG_DELAY_VOTER "OTG_DELAY_VOTER"
#define VCONN_MAX_ATTEMPTS 3
#define OTG_MAX_ATTEMPTS 3
@@ -230,6 +231,7 @@ struct smb_charger {
bool external_vconn;
struct smb_chg_freq chg_freq;
int smb_version;
+ int otg_delay_ms;
/* locks */
struct mutex lock;
@@ -290,6 +292,7 @@ struct smb_charger {
struct delayed_work icl_change_work;
struct delayed_work pl_enable_work;
struct work_struct legacy_detection_work;
+ struct delayed_work uusb_otg_work;
/* cached status */
int voltage_min_uv;