Skip to content

Moto G6 USB-C OTG and VBUS support#244

Open
weidi wants to merge 3 commits into
msm8953-mainline:6.19.5/mainfrom
weidi:codex/moto-g6-usb-otg
Open

Moto G6 USB-C OTG and VBUS support#244
weidi wants to merge 3 commits into
msm8953-mainline:6.19.5/mainfrom
weidi:codex/moto-g6-usb-otg

Conversation

@weidi
Copy link
Copy Markdown

@weidi weidi commented Apr 19, 2026

Enable USB-C OTG host mode on the Motorola Moto G6 (motorola-ali).

The DTS change describes the FUSB302 Type-C controller and models VBUS like the
downstream Android device tree: a fixed usb_otg_vreg regulator fed by the
SMBCHG OTG regulator, without the unused GPIO109 gate.

The SMBCHG change provides the missing PMI8950/SCHG_LITE OTG setup needed for
physical VBUS. DTS-only probing can reach source/host state, but passive OTG
devices remain unpowered without the charger boost register setup.

Tested on a Moto G6:

  • PC/gadget charging: sink/device, SDP, 500 mA
  • Wall charging: DCP, 3 A
  • Passive OTG host: source/host, xHCI root hubs, USB storage enumeration

Generated against 6.19.5/main.

weidi added 2 commits April 19, 2026 14:37
The Moto G6 uses the PMI8950 SMBCHG OTG regulator to source VBUS for
Type-C host mode. The regulator exists, but the PMIC also needs the
downstream SCHG_LITE-style OTG configuration before enabling boost. Without
it the regulator framework reports VBUS as enabled while passive OTG devices
remain unpowered.

Save and restore the USB charge-path and OTG configuration around OTG
regulator use, suspend USB input while sourcing VBUS, configure
command-control/RID mode with hiccup protection, select the 1 A OTG limit,
and disable OTG pulse skip while boost is active.

Also set the SDP input current limit explicitly and disable charger inhibit
during init so charging recovers correctly after switching between charger,
gadget and host roles.

Signed-off-by: weidi <jweidacher@gmail.com>
Describe the Moto G6 FUSB302 Type-C controller and connect it to the DWC3
role switch. Model VBUS like the downstream Android device tree: a fixed
usb_otg_vreg supplied directly by the SMBCHG OTG regulator, without the
unused GPIO109 gate.

This lets TCPM request the charger boost regulator when entering source/host
mode while keeping the existing sink/device charging path for PC and charger
connections.

Signed-off-by: weidi <jweidacher@gmail.com>
@barni2000 barni2000 requested a review from vldly April 21, 2026 22:32
usb_type == POWER_SUPPLY_USB_TYPE_CDP)) {
if (usb_present && !otg_present &&
usb_type == POWER_SUPPLY_USB_TYPE_SDP) {
ret = smbchg_usb_set_ilim(chip, SDP_CURRENT_UA);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be set to value which PROP_INPUT_CURRENT_LIMIT was set to (from usb gadget). dwc node needs usb-psy-name = "qcom-smbchg-usb"; for this to happen.

pinctrl-0 = <&fusb302_int_default>;

vbus-supply = <&usb_otg_vreg>;
usb-role-switch = <&usb3>;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No such property in bindings. This should only be in USB controller node.

Comment thread drivers/power/supply/qcom-smbchg.c Outdated

/*
* Android treats PMI8950 as SCHG_LITE for OTG boost. Apply this
* only while sourcing VBUS so charger/sink mode can keep the PMIC
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in smbchg_init (only for smbchg_lite). No need to cram everything here.

Comment thread drivers/power/supply/qcom-smbchg.c Outdated

ret = qcom_pmic_sec_masked_write(
chip->regmap, chip->base + SMBCHG_OTG_ICFG,
OTG_ILIMIT_MASK, OTG_ILIMIT_1000MA);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be the default at boot and common downstream kernels don't touch it. If not should be in init.

Comment thread drivers/power/supply/qcom-smbchg.c Outdated
enable ? "En" : "Dis");

if (enable && !chip->otg_usb_input_suspended) {
ret = smbchg_usb_enable(chip, false);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and smbchg_usb_path_for_otg seems to be taken from ext_otg_vreg regulator ops. But that regulator isn't used on other devices. Also it doesn't look like it's used on G6 too. It seems to be fake regulator with workarounds for external regulator to not interfere with charger.

Comment thread drivers/power/supply/qcom-smbchg.h Outdated
Comment thread arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
Comment thread arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts Outdated
@weidi
Copy link
Copy Markdown
Author

weidi commented May 28, 2026

Hi @vldly,

I have completely refactored the patch set to address your review feedback and clean up the implementation. The entire series has been tested and verified on physical hardware.

Here is a summary of the refactoring and corrections made:

Removed Dynamic Save/Restore Logic: The complex, dynamic register save/restore logic has been completely deleted from the qcom-smbchg driver.
Probe-Time HW Initialization: The booster hardware configuration (enabling hiccup mode, configuring command-control/RID mode, setting the 1A limit, and disabling pulse skipping) has been moved to probe time (smbchg_init) specifically for smbchg_lite (PMI8950) devices. It runs once during driver initialization, keeping the dynamic smbchg_otg_switch lightweight and safe.
Device Tree Cleanup: The dummy fixed regulator (usb-otg-switch / usb_otg_vreg) has been deleted. The FUSB302 Type-C controller's vbus-supply now points directly to the real PMIC regulator &otg_vbus.
Mainline Charger Inhibit Alignment: Reverted the unrelated CHG_INHIBIT_DIS change back to mainline CHG_INHIBIT_EN.
Resolved AICL Uninitialized Warning: Fixed the pre-existing uninitialized ret warning in smbchg_handle_aicl_done.
Fixed Dedicated Wall Charging (DCP/CDP) Bug: Resolved a critical VBUS charging suspend bug that occurred when linking the USB controller to the PMIC via usb-psy-name. (See below for details).
The refactored branch has been successfully built, deployed, and tested on-device. Both OTG host mode (tested with passive USB flash drive and USB Hub) and socket charging (stable at ~600mA+ charging current) are working beautifully and are stable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants