Skip to content

Add support for GPIO line names via libgpiod - #4

Open
mhei wants to merge 17 commits into
EVerest:everestfrom
chargebyte:feature/libgpiod
Open

Add support for GPIO line names via libgpiod#4
mhei wants to merge 17 commits into
EVerest:everestfrom
chargebyte:feature/libgpiod

Conversation

@mhei

@mhei mhei commented Apr 29, 2026

Copy link
Copy Markdown

The good old sysfs based user-space interface with GPIO numbers is obsolete since several years.

This PR add support for an alternative approach: instead of plain integers, user can configure the required GPIO lines using a GPIO line name as usually defined in the Device Tree for the board. For this, this PR relys on libgpiod. Support for using libgpiod can be switched on at compile time, to keep backwards compatiblity, it is disabled by default.

The new dependency is not pulled in automatically but is expected to be provided by the environment.

The tested libgpiod version is v2.0.1 - since this is currently the version that we (chargebyte) bundle in our kirkstone builds on our targets.

Even if the library is compiled with libgpiod support, then it is still possible to use integer numbers and the older sysfs interface.

Sidenote 1: I pulled in the commit from #3 - just wanted to have it included when testing. I can remove it once there is a decision/feedback in that PR.

Sidenote 2: I tested only on our Charge SOM platform so far and fixed a 64-bit issue from an older commit in this branch.

I'm unsure regarding the ADDITIONAL_CONTENT stuff in the packaging file - this is untested and I hope someone with more expertise can comment on it.

Comment thread src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc Outdated
Comment thread conf/libnfc-nxp.conf
@barsnick

Copy link
Copy Markdown

@cburandt Friendly ping ;-)

@mhei

mhei commented Jun 8, 2026

Copy link
Copy Markdown
Author

Any comments, positive or negative, are welcome, as is regression testing on existing platforms.

@mhei

mhei commented Jun 11, 2026

Copy link
Copy Markdown
Author

I had problems to cross-compile the library and the PN7160TokenProvider using Yocto kirkstone, so I added a commit here to create a shared library. This requires also a small change in the CMake file of PN7160TokenProvider, you can find it here as example: https://github.com/chargebyte/everest-core/commits/feature/pn7160-as-shared-lib/

@mhei

mhei commented Jun 29, 2026

Copy link
Copy Markdown
Author

Just FYI: I'm already working on the next improvement step (dynmaic config via EVerest module config), see the branch here: https://github.com/chargebyte/linux_libnfc-nci/tree/feature/libgpiod-with-cfg-call I'm just wondering, whether I should merge this into this PR here? (corresponding branch for everest-core: https://github.com/chargebyte/everest-core/tree/feature/pn7160-as-shared-lib-with-dyn-cfg)

@cburandt cburandt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sorry for being unresponsive. I did a quick test with hardware and that required a small change in order to work (see below).

I will have another look at the ADDITIONAL_CONTENT and the libgpiod related things soon.

Comment on lines 1087 to 1091
int value;
int isfound = GetNxpNumValue(name, &value, sizeof(&value));
int isfound = GetNxpNumValue(name, &value, sizeof(value));
if (isfound > 0) {
return value;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
int value;
int isfound = GetNxpNumValue(name, &value, sizeof(&value));
int isfound = GetNxpNumValue(name, &value, sizeof(value));
if (isfound > 0) {
return value;
}
// GetNxpNumValue only dispatches on sizeof(unsigned long long/short/char)
// (see above); a 4-byte int hits the default case and returns false. Use unsigned
// long so the length matches a supported case.
unsigned long value = 0;
int isfound = GetNxpNumValue(name, &value, sizeof(value));
if (isfound > 0) {
return (int)value;
}

Had to do this change in order to make it work on a test setup (RPi5+I2C-attached eval board).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch! But for some reason, I cannot add your suggestion directly here with Github... will do with new commit and to be on the safe side for later, I'd add the "int" case to GetNxpNumValue, too.

@lategoodbye

Copy link
Copy Markdown

@cburandt Did you had the time to test Michael's changes?

@cburandt

Copy link
Copy Markdown
Collaborator

@cburandt Did you had the time to test Michael's changes?

Hello @lategoodbye , @mhei I started a review now (but will likely finish not today, but tomorrow).

@cburandt cburandt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM in general.

Find some comments below.
Don't consider the deleting of the "virtual" keywords a mandatory change; I prefer do have only one of virtual/override/final, but that's more a matter of taste (and accordance with the core guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#c128-virtual-functions-should-specify-exactly-one-of-virtual-override-or-final)

Concerning the "ADDITIONAL_CONTENT" in the CMakeLists.txt, I think it's not required.

**
****************************************************************************/
int NfccReset(void* pDevHandle, NfccResetType eType);
virtual int NfccReset(void* pDevHandle, NfccResetType eType) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual int NfccReset(void* pDevHandle, NfccResetType eType) override;
int NfccReset(void* pDevHandle, NfccResetType eType) override;

** Returns None
****************************************************************************/
void EnableFwDnldMode(bool mode);
virtual void EnableFwDnldMode(bool mode) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual void EnableFwDnldMode(bool mode) override;
void EnableFwDnldMode(bool mode) override;

** Returns Current mode download/NCI
****************************************************************************/
bool_t IsFwDnldModeEnabled(void);
virtual bool_t IsFwDnldModeEnabled(void) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual bool_t IsFwDnldModeEnabled(void) override;
bool_t IsFwDnldModeEnabled(void) override;

int GetIrqState(void* pDevHandle);
int GetNfcState(void* pDevHandle);
****************************************************************************/
virtual int GetIrqState(void* pDevHandle) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual int GetIrqState(void* pDevHandle) override;
int GetIrqState(void* pDevHandle) override;

** Returns None
**
****************************************************************************/
virtual void Close(void *pDevHandle) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual void Close(void *pDevHandle) override;
void Close(void *pDevHandle) override;

*****************************************************************************/
int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite);
void Close(void* pDevHandle);
virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override;
int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override;

**
****************************************************************************/
NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle);
virtual NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle) override;
NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle) override;

**
****************************************************************************/
int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead);
virtual int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) override;
int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) override;

*****************************************************************************/
int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite);
void Close(void* pDevHandle);
virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override;
int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override;

Comment thread CMakeLists.txt Outdated
Comment on lines +369 to +373
"set(LIBNFCNCI_LIBGPIOD @LIBNFCNCI_LIBGPIOD@)"
"if(LIBNFCNCI_LIBGPIOD)"
" find_dependency(PkgConfig)"
" pkg_search_module(LIBGPIOD REQUIRED libgpiodcxx)"
"endif()"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Did you find this to be required in testing? Pretty sure this is not: You switched to building a shared lib which depends only PRIVATE-ly on libgpiod. Provided libgpiod is a static lib, it will have become part of the nfc-nci lib already, so no need for the client to find it. Same for thread.
But I didn't test.

@mhei

mhei commented Jul 30, 2026

Copy link
Copy Markdown
Author

Thanks for your feedback. I will look into it and address the points after returning from holidays next week.

mhei and others added 17 commits August 11, 2026 16:01
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Signed-off-by: Christoph Burandt <christoph.burandt@pionix.de>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Invalid file descriptor is -1, values >= must be considered valid.

While at, get rid of the Close method is derived class since
the functionality is the same for all derived classes.

Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
This uses a proprietary ioctl which will not work with default
I2C or SPI interface devices on Linux.
I guess this is left-over copy&paste garbage.
Remove it since there seems no user of this methods.

Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Destination buffer must not overflow, so check size of buffer
and string length.

Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
We need to pass the size of the target variable, not
the size of the pointer to it.

This is important on platforms where sizeof(pointer) != sizeof(int)

Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
This should make it more clear, that mixing is undefined behavior.

Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
We can re-use kernel's maximum GPIO line name length here
instead of a random hard-coded size.

While at, improve the debug messages to support users when using
the new feature.

Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
On usual platforms, int is normally 4 byte which hits the
default case in GetNxpNumValue and thus returns an error.

Signed-off-by: Christoph Burandt <christoph.burandt@pionix.de>
Signed-off-by: Michael Heimpold <mhei@heimpold.de>
On some platforms, the size of int differs from size of long.

When an int is passed as parameter to this function, then the default
case would trigger without assigning a value. This is not desired.

But we need to guard the second case statement, because the compiler
requires different values here - which would fail on platforms
where both sizes are equal.

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
@mhei
mhei force-pushed the feature/libgpiod branch from e4442be to 7524e3d Compare August 28, 2026 08:03
@mhei

mhei commented Aug 28, 2026

Copy link
Copy Markdown
Author

Sorry for the long delay, I finally found the time to rework this PR and folded in your valuable feedback. I hope, that I did not forget a point, a second review would be appreciated.

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.

4 participants