Page MenuHomeFreeBSD

nctgpio: Refactor and add support for NCT6779, NCT6116D and Winbond 83627DHG
Changes PlannedPublic

Authored by on Dec 29 2022, 9:36 AM.
Referenced Files
Unknown Object (File)
Thu, Mar 23, 6:07 AM
Unknown Object (File)
Thu, Mar 2, 4:52 PM
Unknown Object (File)
Feb 12 2023, 6:48 PM
Unknown Object (File)
Jan 6 2023, 4:24 AM
Unknown Object (File)
Dec 30 2022, 3:32 AM


Group Reviewers
Contributor Reviews (base)

Add support for old chips:

  • Nuvoton NCT6116D
  • and Winbond 83627DHG

but also for a more recent one:

  • Nuvoton NCT6779

The refactoring help handle chips like the NCT6779 that span the control of a
given GPIO group across more than one logical device.

I modified gpioctl, en passant, to avoid listing invalid pins (unless verbose
is enabled). It help handle somewhat gracefully the Winbond 83627DHG having its
first group being GPIO2.

Successfully tested with Nuvoton NCT6116D and Nuvoton NCT6779.

Diff Detail

rG FreeBSD src repository
Lint Passed
No Test Coverage
Build Status
Buildable 48964
Build 45853: arc lint + arc unit

Event Timeline


I'm puzzled by this (original) code and that gpioctl don't allow you to clear any flags.
If for any reason I set some inversion flag on a pin, how am I supposed to clear it?

gpioctl -c 40 OUT IO # Set the INVOUT flag and call nct_set_pin_inverted with 0
gpioctl -c 40 IN II # Set the INVIN flag and call nct_set_pin_inverted with 1, i.e., effectively enabling inversion
gpioctl -c 40 OUT # Don't change the flags and don't call nct_set_pin_inverted

It looks like we're missing gpioctl -c 40 -IO to remove the INVOUT flag and call nct_set_pin_inverted with 0.

Note that NCT chips don't seems to distinguish between input inversion and output inversion.


(Replying to myself)
To avoid patching gpioctl, I propose the following code. It solve two problems:

  • allow clearing the inversion flag
  • and help ensure INVIN and INVOUT are treated as a single flag, i.e., gpioctl -c 40 OUT IO set INVIN too and gpioctl -c 40 OUT clear both.
/* inversion */
pin->gp_flags &= ~(GPIO_PIN_INVIN | GPIO_PIN_INVOUT);
if ((flags & (GPIO_PIN_INVIN | GPIO_PIN_INVOUT)) != 0) {
	nct_set_pin_inverted(sc, pin_num, 1);
	pin->gp_flags |= (GPIO_PIN_INVIN | GPIO_PIN_INVOUT);
} else
	nct_set_pin_inverted(sc, pin_num, 0);

Increase verbosity to direct i/o code path (iores != 0)

I would like this code to be the basis to add support for NCT5585D but this chip is so weird, I'll have to rework things.