Skip to content

fusb302: Fairchild FUSB302B USB-C / USB-PD controller driver#2231

Open
b1nc0d3x wants to merge 1 commit into
freebsd:mainfrom
b1nc0d3x:submit/d4-fusb302
Open

fusb302: Fairchild FUSB302B USB-C / USB-PD controller driver#2231
b1nc0d3x wants to merge 1 commit into
freebsd:mainfrom
b1nc0d3x:submit/d4-fusb302

Conversation

@b1nc0d3x
Copy link
Copy Markdown

Summary

Add an in-tree driver for the Fairchild (now ON Semiconductor)
FUSB302B USB Type-C port controller. The chip is an i2c slave
that implements CC1/CC2 sensing, BMC PHY for USB Power Delivery
messages, DRP toggle for role detection, and a VBUS measure ADC.
It is the Type-C controller used on the RockPro64, Pinebook Pro,
ROCK Pi 4, Khadas Edge, and several Chromebook designs around the
RK3399 era.

The driver supplies the struct usbc_tcpc_ops vtable consumed by
the usbc(4) policy framework (D3, #2211). All PD message
framing, policy state, VDM negotiation, and DisplayPort altmode
logic lives in usbc; this driver is the chip-specific I2C /
interrupt / FIFO half.

Functional coverage:

  • SRC + SNK port roles, with DRP toggle for autonomous role
    discovery on cold plug.
  • USB PD R3.2 messaging via the BMC TX/RX FIFOs (SOP only;
    SOP'/SOP'' cable messages scaffolded but not exercised).
  • Spec rev autoselect with PD 2.0 / PD 3.0 fallback (sysctl-
    selectable for compatibility testing against picky sinks).
  • Soft-reset and hard-reset paths.
  • Polled DRP retoggle on lost partner -- recovers from sinks
    that momentarily drop CC during their own re-orientation.
  • IRQ-driven; uses sx(9) for the soft state and never holds
    a spinlock across an I2C transaction (FUSB302's transfers can
    sleep on bus arbitration).
  • Debug output gated behind dev.fusb302.<N>.debug, default 0.

Modeled functionally on the Linux
drivers/usb/typec/tcpm/fusb302.c driver but is a clean
reimplementation -- no code copied from Linux. Linux is the
reference for register sequencing only; the state machine,
locking discipline, and tunables are FreeBSD-native.

Includes a Rockchip-specific helper at
sys/arm64/rockchip/rk3399_fusb302_helper.c (built as a
separate module) that bridges FUSB302's role/orientation
detection to the RK3399 Type-C PHY mode-switch. This file is the
only piece in the review that is Rockchip-specific; the
fusb302(4) driver itself runs on any platform that exposes an
i2c bus and a level-sensitive GPIO for INT_N.

Dependencies

Depends on D3 (usbc framework, #2211) being committed first.
The vtable consumed (struct usbc_tcpc_ops, usbc_pd_policy_*
entry points) is defined there. Build will fail without D3
applied.

What's deliberately NOT in this review

Test plan

  • Pine64 RockPro64 v2.1 + XYM W156F1 USB-C portable monitor:
    cold boot completes a full PD source contract (SRC_CAP ->
    REQUEST -> ACCEPT -> PS_RDY) and a DP altmode entry within
    ~1.5 s of probe attach. Verified across 20+ plug/unplug
    cycles; no leaked state, no IRQ storm (cf. D1, rk_gpio: implement PIC masking methods and mask unhandled IRQs #2197, the
    rk_gpio PIC fix that makes this even reachable on cold boot).
  • Same board, USB-A type-C cable (no DP altmode advertised):
    PD source contract still completes; altmode entry is
    correctly declined; downstream rk_typec_phy stays in USB
    mode.
  • Spec-rev forced via dev.fusb302.0.pd_spec_rev=20 (PD 2.0
    only) on three different PD sinks (XYM W156F1, Anker 535
    dock, a counterfeit Apple-pattern cable): all complete
    contract without falling back further. pd_spec_rev=30
    (PD 3.0) also completes on the W156F1 and the Anker but is
    rejected by the counterfeit cable, which is expected.
  • Hard-reset recovery: forced via sysctl
    dev.fusb302.0.force_hard_reset=1 mid-contract. Driver
    returns to USBC_PD_SRC_STARTUP and renegotiates within
    300 ms.
  • kldload fusb302; kldload rk3399_fusb302_helper; kldunload rk3399_fusb302_helper; kldunload fusb302 -- no leaks, no
    interrupts left enabled at the controller, no spurious GPIO
    edges observed under dtrace.

Size note

At ~4.5k lines this is on the larger side for a single
Differential. If reviewers prefer it split, the natural cut is:

  • D4a: fusb302.c + fusb302_var.h +
    sys/modules/fusb302/Makefile (the platform-independent
    driver, ~4.4k lines).
  • D4b: rk3399_fusb302_helper.c + its Makefile (Rockchip-
    specific extcon/typec-phy glue, ~140 lines).

I left it as one review because D4b is functionally meaningless
without D4a, and reviewing the helper in isolation is harder
than reviewing it as a small section of the same patch. Happy
to split on request.

Suggested reviewers

bsdimp, emaste, wulf7 (recent USB / iicbus committers per
git log); evadot, mhorne (sys/arm64/rockchip).

Add an in-tree driver for the Fairchild (now ON Semiconductor)
FUSB302B USB Type-C port controller.  The chip is an i2c slave
implementing CC1/CC2 sensing, BMC PHY for USB Power Delivery
messages, DRP toggle for role detection, and a VBUS measure ADC.
It is the Type-C controller used on the RockPro64, Pinebook Pro,
ROCK Pi 4, Khadas Edge, and several Chromebook designs around the
RK3399 era.

The driver supplies the struct usbc_tcpc_ops vtable consumed by
the usbc(4) policy framework (D3).  All PD message framing,
policy state, VDM negotiation, and DisplayPort altmode logic lives
in usbc; this driver is the chip-specific I2C / interrupt / FIFO
half.

Functional coverage:

  - SRC + SNK port roles, with DRP toggle for autonomous role
    discovery on cold plug.
  - USB PD R3.2 messaging via the BMC TX/RX FIFOs (SOP only;
    SOP'/SOP'' cable messages scaffolded but not exercised).
  - Spec rev autoselect with PD 2.0 / PD 3.0 fallback (sysctl-
    selectable for compatibility testing against picky sinks).
  - Soft-reset and hard-reset paths.
  - Polled DRP retoggle on lost partner -- recovers from sinks
    that momentarily drop CC during their own re-orientation.
  - IRQ-driven; uses sx(9) for the soft state and never holds a
    spinlock across an I2C transaction.
  - Debug output gated behind dev.fusb302.<N>.debug, default 0.

Modeled functionally on the Linux drivers/usb/typec/tcpm/fusb302.c
driver but is a clean reimplementation -- no code copied from
Linux.  Linux is the reference for register sequencing only; the
state machine, locking discipline, and tunables are FreeBSD-native.

Includes a Rockchip-specific helper at
sys/arm64/rockchip/rk3399_fusb302_helper.c (built as a separate
module) that bridges FUSB302's role/orientation detection to the
RK3399 Type-C PHY mode-switch.  This is the only Rockchip-specific
piece; the fusb302(4) driver itself runs on any platform that
exposes an i2c bus and a level-sensitive GPIO for INT_N.

Depends on D3 (usbc framework, PR freebsd#2211) being committed first.
Build will fail without D3 applied.

Signed-off-by: Kyle Crenshaw <B1nc0d3x@gmail.com>
@github-actions
Copy link
Copy Markdown

Thank you for taking the time to contribute to FreeBSD!

Some of files have special handling:

Important

@evadot wants to review changes to sys/arm64/rockchip

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.

1 participant