Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsupported nfc device in lenovo T470 #455

Open
Eik-S opened this issue Oct 4, 2017 · 75 comments
Open

Unsupported nfc device in lenovo T470 #455

Eik-S opened this issue Oct 4, 2017 · 75 comments

Comments

@Eik-S
Copy link

Eik-S commented Oct 4, 2017

Unfortunately, the nfc module of lenovo T470 is not yet supported.

Neither lsusb is showing the device:
Bus 002 Device 002: ID 0bda:0316 Realtek Semiconductor Corp.
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 138a:0097 Validity Sensors, Inc.
Bus 001 Device 004: ID 5986:111c Acer, Inc
Bus 001 Device 002: ID 058f:9540 Alcor Micro Corp. AU9540 Smartcard Reader
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Is there any progress on this?
Thanks.

@totakura
Copy link

I believe the NFC module is connected via I2C bus. Lets see if it is being detected there; can you install i2c-tools and run

i2cdetect -l

@Eik-S
Copy link
Author

Eik-S commented Oct 26, 2017

Output is:

i2c-3	unknown   	DPDDC-A                         	N/A
i2c-1	unknown   	i915 gmbus dpb                  	N/A
i2c-6	unknown   	Synopsys DesignWare I2C adapter 	N/A
i2c-4	unknown   	DPDDC-B                         	N/A
i2c-2	unknown   	i915 gmbus dpd                  	N/A
i2c-0	unknown   	i915 gmbus dpc                  	N/A
i2c-5	unknown   	DPDDC-C                         	N/A

@totakura
Copy link

totakura commented Nov 6, 2017

My only suspicion is the Synopsis DesignWare I2C adapter; I wonder what that is. The rest are I2C inputs for plug-and-play monitors.

Do you also dual boot Windows? If yes, could you please check the bus under which it is being detected in the device manager?

Edit: The I2C adapter is not NFC

@derTobsch
Copy link

I have the same problem and my output is

i2c-3	unknown   	DPDDC-A                         	N/A
i2c-1	unknown   	i915 gmbus dpb                  	N/A
i2c-6	unknown   	Synopsys DesignWare I2C adapter 	N/A
i2c-4	unknown   	DPDDC-B                         	N/A
i2c-2	unknown   	i915 gmbus dpd                  	N/A
i2c-0	unknown   	i915 gmbus dpc                  	N/A
i2c-5	unknown   	DPDDC-C                         	N/A

I do not have a dual boot with windows. Only ubuntu 17.10 on a t470s

@derTobsch
Copy link

if someone needs support or information from the system please ask. It would be nice if there will be a driver for this nfc module.

@lbeltrame
Copy link

The device manager reports the NFC reader as NXP Semiconductors(Proximity) NXP Near Field Proximity Provider. Its "location" is under an I2C controller, "Serial I/O I2C Intel Host Controller - 9D60" (translated from my Language so it may be different from the English version). The "bus number" in the device manager is 0, the "BIOS name" is "_SB.PCI0.I2C0.NFC1".

The I2C controller listed (Intel Host Controller) is under PCI bus 0, device 21.

I'll keep Windows here for a couple more days before wiping it, so if need be, I can provide more details.

@Roxxor91
Copy link

Hey! I would like to participate in solving this issue!
From the FRU list (https://download.lenovo.com/parts/ThinkPad/t470_frubom_20170731.pdf) I found that the NFC is this one: https://fccid.io/MCLT77H747/Users-Manual/User-Manual-rev-4-3127142.html
FOXCONN Part No. T77H747.10
-> NFC (NXP NPC300) Module

@tuxflo
Copy link

tuxflo commented Jan 20, 2018

The same NFC/smartcard reader is installed in the Lenovo Thinkpad Yoga 260.
Since the driver seems not to work with linux my question is: is the (compiled) Windows version of libnfc able to use the Windows drivers (the device shows status "Usable" in the device manager)?
If yes I would like to try to compile it on my windows system and share the results...

@Coffee2CodeNL
Copy link

Same story in the T580, also the Foxconn NXP NPC300.

Wish it worked :(

@RaphaelWimmer
Copy link

RaphaelWimmer commented Jun 12, 2018

Some more details and clarifications:

  • NXP does not have any info on a "NPC300" chip/solution. It seems to me that this is just another name for an NFC chip from the PN7xxx range (or a name for a combination of chip and antenna).
  • NXP does not seem to support libnfc but provides their own libnfc-nci for Linux according to these interesting Webinar slides.
  • There are some tips on compiling the libnfc-nci kernel driver in the Webinar slides and NXP application note AN11697.
  • However, there is a major problem: the chip needs to be enabled (activated) through a GPIO pin that drives VEN high. AFAICT, the device will only appear on the I2C bus if it is activated in this way. Unless you have the schematics for your motherboard, the only way to find out which of the CPU's GPIO pins is connected to the NXP chip is to activate every single one of them and check whether the NXP chip appears on the I2C bus. As lots of other stuff might be connected to these GPIO pins, I'm a little bit hesitant to try this out.
  • It seems that the NXP chips usually have an I2C address of 0x28 or 0x29. So, if the chip is enabled, i2cdetect should detect a device at this address.

The correct way to find out which I2C devices are connected to an I2C bus (and are responding) is the following:

modprobe i2c-dev      # to make the I2C buses available on /dev
i2cdetect -l     # to find all I2C buses 
i2cdetect 0    # to find out which devices are connected to bus i2c-0

This can only tell you the addresses of devices on the bus (e.g., "0x28"), not what they actually are, however.
Despite the warning that "This program can confuse your I2C bus, cause data loss and worse!", probing the I2C bus this way has never caused any problems for me.

Most of the I2C buses you will see with i2cdetect -l belong to the graphics chip (e.g., everything with "DDC" in the name). The most probable bus to find the NFC chip would be the SMBus (i2c-0 smbus SMBus I801 adapter at efa0 SMBus adapter) in my case.

@pccr10001
Copy link

pccr10001 commented Jun 24, 2018

Hi. I found something from DSDT table in my X1C 6th.
According to the picture, I think 0x0029 is the I2C address, and GPIO lists are the pins definition.
The GPIO pin 0x006C is active high, is it VEN pin?
default
NPC300 datasheet

@RaphaelWimmer
Copy link

Oh, I didn't know that this can be stored in the DSDT (unfortunately, the DSDT on my HP Elitebook 1030 G2 only contains "0x0000" as pin lists).
I guess GPIO 0x6C is the connected to the IRQ pin of the NFC module which notifies the kernel that a NFC chip has been detected. GPIO 0x27 and 0x64 are probably connected to VEN and DWL_REQ (enable firmware update mode - potentially dangerous to keep enabled).

@jr64
Copy link

jr64 commented Aug 8, 2018

I have a Thinkpad T480s which uses the same NPC300 chip and I partially succeeded getting it to run under Ubuntu 18.04.
Libnfc-nci (https://github.com/NXPNFCLinux/linux_libnfc-nci/) has a mode where it uses /sys/class/gpio to communicate with the hardware. Since that seemed easier to play around with than a kernel module, I decided to start with that.

My DSDT is the same as the one @pccr10001 posted, so I guess the configuration is the same.

I edited the pins in src/halimpl/pn54x/tml/i2c/phTmlNfc_alt.h like this:

 #define I2C_BUS         "/dev/i2c-6"
 #define I2C_ADDRESS     0x29
 #define PIN_INT         360+0x6c
 #define PIN_ENABLE      360+0x64

I got the bus number from ic2detect -l which looks like this:

i2c-3	unknown   	DPDDC-A                         	N/A
i2c-1	unknown   	i915 gmbus dpb                  	N/A
i2c-6	unknown   	Synopsys DesignWare I2C adapter 	N/A
i2c-4	unknown   	DPDDC-B                         	N/A
i2c-2	unknown   	i915 gmbus dpd                  	N/A
i2c-0	unknown   	i915 gmbus dpc                  	N/A
i2c-5	unknown   	DPDDC-C                         	N/A

Bus 6 was the only one that made sense to me and indeed it worked.

The i2c address and ports are from the DSDT, finally the offset 360 is from /sys/class/gpio/gpiochip360/base

Afterwards I configured the library like this (not sure if it is a pn7150 or pn7120 but I guess 7150 because according to data sheets I found the chip supports tags of type 5 which the 7120 does not):

./configure --enable-pn7150 --enable-alt --sysconfdir=/etc

Then I ran make and make install and finally was able to start the demo app:

 sudo ./nfcDemoApp poll
#########################################################################################
##                                       NFC demo                                      ##
#########################################################################################
##                                 Poll mode activated                                 ##
#########################################################################################
                              ... press enter to quit ...

Waiting for a Tag/Device...

	NFC Tag Found

		Type : 		'Type A - Mifare Classic'
		NFCID1 :    	'XX XX XX XX '
		NDEF Content : NO, mode=1, tech=8

		RAW Tag transceive failed
		Type : 		'Type A - Mifare Classic'
		NFCID1 :    	'XX XX XX XX '
		NDEF Content : NO, mode=1, tech=8

		RAW Tag transceive failed
		Type : 		'Type A - Mifare Classic'
		NFCID1 :    	'XX XX XX XX '
		NDEF Content : NO, mode=1, tech=8

		RAW Tag transceive failed
		Type : 		'Type A - Mifare Classic'
		NFCID1 :    	'XX XX XX XX '
		NDEF Content : NO, mode=1, tech=8

		RAW Tag transceive failed
	NFC Tag Lost

Waiting for a Tag/Device...

As you can see it correctly detected the Mifare classic card I tested. I'm not sure if the RAW Tag transceive failed means that something is still not working. Maybe my card is not a standard Mifare Classic but a modified version, I'm not sure and don't have anything else to test.

I guess the next step would be to try to get the proper kernel module to run, it shouldn't be too hard with the configuration already known.

One thing I noticed is that the touchpad does not seem to play well with the nfc driver. whenever I start it, the touchpad becomes laggy, the mouse pointer sometimes jumps around and acceleration seems to stop working. This persists for a few seconds, then everything works again and then it starts being buggy again. This even persists after I stop the nfc demo until I reboot the system. I don't have much experience with i2c so if anyone could point me in the right direction that would be great.

Also I have never worked with NFC before, am I correct in assuming that libnfc and libnfc-nci are not compatible so even if we got it to work, most of the software out there would have to be heavily modified to work on our machines?

@mvdnes
Copy link

mvdnes commented Aug 8, 2018

@jr64 I can confirm this also works on my regular T480 with Arch Linux. Same DSDT file, and the i2c bus has the same name altough it is sometimes on /dev/i2c-0 and sometimes on /dev/i2c-1.

The demo app works with poll, and write on a small tag, and share also works with my Android phone.

I would also like to point out the path /sys/bus/i2c/devices/i2c-NXP1001:00/, which is present on my system. Maybe that can be used to determine the i2c bus more reliably.

@pccr10001
Copy link

@JC64 This solution works on my X1C and card emulation works too, I am using Ubuntu 18.04.1.

@jr64
Copy link

jr64 commented Aug 9, 2018

Update: I just modified the i2c kernel driver (https://github.com/NXPNFCLinux/nxp-pn5xx) to support ACPI and autoconfigure itself. Seems to work fine to me. I'll post the code as soon as I have cleaned it up.

However, this still does not fix the touchpad issues I am experiencing. Does anyone else have this problem? Any ideas how to fix? I'm assuming the touchpad is also connected via i2c and the driver is somehow interfering with it?

@jr64
Copy link

jr64 commented Aug 10, 2018

For anyone interested, I just uploaded the first version of my modified kernel driver: https://github.com/jr64/nxp-pn5xx

@pccr10001
Copy link

pccr10001 commented Aug 10, 2018

@jr64 Here is the solution of the trackpoint problem.
My trackpoint is working now.
You need the latest kernel to work for RMI bus.

https://wiki.archlinux.org/index.php/Lenovo_ThinkPad_X1_Carbon_(Gen_6)#TrackPoint_and_Touchpad_issues

@jr64
Copy link

jr64 commented Aug 10, 2018

@pccr10001 Thanks, that seemed really promising but unfortunately it looks like they put an Elan touchpad and not a Synaptics in the T480s.

To quote from https://patchwork.kernel.org/patch/10330857/:

"- the T480s is using an Elan touchpad, so that's a different story"

Luckily it looks like there is work being done on Elan too (https://patchwork.kernel.org/patch/10324633/) but it's not yet included in the kernel I'm running.

Anyways, at least I'm fairly certain now that the problem is with the touchpad driver and not with the code I wrote for the NFC module.

@jr64
Copy link

jr64 commented Aug 10, 2018

Oh and another funny detail: the only way I found to fix the slow trackpad without rebooting the system is to close and open the notebook. Reloading the psmouse driver seems to do nothing, but putting the device to sleep and waking it up again fixes it permanently (well at least until I use NFC again).

@spielkind
Copy link

I'm still a bit confused, I compiled the DemoApp with the manual GPIO changes, and it worked:
#########################################################################################
##                                       NFC demo                                      ##
#########################################################################################
##                                 Poll mode activated                                 ##
#########################################################################################
                              ... press enter to quit ...

Waiting for a Tag/Device...

	NFC Tag Found

        Type :         'Type A'
        NFCID1 :    	'04 22 2B C2 B6 46 80 '
		NDEF Content : NO, mode=1, tech=1

	Not a MIFARE card
	NFC Tag Lost

Waiting for a Tag/Device...

I'm on a X280:
/sys/bus/i2c/devices/i2c-NXP1001:00 -> ../../../devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-NXP1001:00

But why would I need the kernel module adjusted by @jr64 , and how can I confirm that it worked after loading. Also are there any client tools, beside the demoapp, which work right now?

@jr64
Copy link

jr64 commented Aug 13, 2018

@spielkind The kernel module has two advantages:

  1. it configures itself from ACPI so no need to manually find out the correct GPIO ports
  2. driving GPIO pins from userland through /sys/class/gpio is kind of "hacky", a kernel module is the "proper" variant for such a task. But of course, at the end of the day, both work fine.

As for how to test: if you configure the library with "--enable-i2c" instead of "--enable-alt" it will only work if the kernel modules is loaded.

@blasty
Copy link

blasty commented Nov 2, 2018

Thanks @jr64 and others for the progress on this. I've gotten this to work (sort of) on a T480s with @jr64's kernel module and libnfc-nci-R2.2. However, with the nfcDemoApp (in poll mode) I have a very poor detection rate of tags, and haven't seen any succesfull NDEF record reading yet. Has anyone experienced similar issues?

Edit: the detection rate for a passport with RFID works a lot better (as opposed to two random RFID-capable bank cards I have), though Im getting different NFCID values etc. every tap. I guess something with the configuration/calibration of the RF stuff is really off.. :-/

@dlezcano
Copy link

dlezcano commented Dec 4, 2018

@jr64 : did you plan to upstream the driver ? I tried it on a x280 and it works as far as I can tell. That would be an improvement of the x280 support on Linux.

@dlezcano
Copy link

dlezcano commented Dec 4, 2018

I have been throught the upstream kernel and found the following commit:

commit 0a5942c8e1480db4b8ee7a8d643e4945ef2f8fed
Author: Robert Dolca robert.dolca@intel.com
Date: Mon Jan 26 13:13:37 2015 +0200

NFC: Add ACPI support for NXP PN544

Currently there is no support for ACPI.
This patch uses the following configuration:
        - Device id: NXP5440
        - Pin mapping:
                - 0 IRQ pin
                - 1 enable pin
                - 2 firmware pin

Signed-off-by: Robert Dolca <robert.dolca@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

So at this point I assume the ACPI is supported in mainline since 2015. But if we look closely at the ACPI table and match hid we have in this driver:

static const struct acpi_device_id pn544_hci_i2c_acpi_match[] = {
{"NXP5440", 0},
{}
};

But on my x280, the ACPI table is:
[ ... ]
Name (_HID, "NXP1001") // _HID: Hardware ID
[ ... ]
Except I'm missing something, it should be NXP5440.

@dlezcano
Copy link

dlezcano commented Dec 4, 2018

dsdt table looks buggy:
acpidump > acpidump
acpixtract -a acpidump
iasl -d dsdt.dat
iasl -tc dsdt.dsl

Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20180105
Copyright (c) 2000 - 2018 Intel Corporation

Compiler aborting due to parser-detected syntax error(s)
dsdt.dsl 264: Name (SS4, One)
Error 6126 - ^ syntax error, unexpected PARSEOP_NAME

ASL Input: dsdt.dsl - 34418 lines, 1065629 bytes, 15154 keywords
Hex Dump: dsdt.hex - 230 bytes

Compilation complete. 1 Errors, 0 Warnings, 0 Remarks, 0 Optimizations

@dlezcano
Copy link

dlezcano commented Dec 4, 2018

And even worse, run:
sudo fwts syntaxcheck -
and admire the result on my beautiful ultra expensive x280.

Test |Pass |Fail |Abort|Warn |Skip |Info |
---------------+-----+-----+-----+-----+-----+-----+
syntaxcheck | 11| 26| | | | |
---------------+-----+-----+-----+-----+-----+-----+
Total: | 11| 26| 0| 0| 0| 0|
---------------+-----+-----+-----+-----+-----+-----+

WTF!

@vvug
Copy link

vvug commented Feb 11, 2019

@jr64 Same question here. Do you think your driver can be upstreamed? Thanks!

@dileks
Copy link

dileks commented May 13, 2019

Just want to let you know...

With the patch series "[PATCH v2 00/12] NFC: nxp-nci: clean up and support new ID" (see [1]) I was able to get my NFC chip NXP NFC300 ("NXP1001") run on my Lenovo ThinkPad T470 with the NFC nxp-nci driver shipped with Linux v5.1.1.

Furthermore, I can acces, list and poll with neard (daemon) v0.16 and neard-tools from Debian/buster.

There is no need for nxp-pn5xx driver and libnfc-nci from NXP.

Before this I expermented with jr64 nxp-pn5xx (acpi support) and libnfc-nci from NXP and had sucess with running the demo-app. I saw in the logs:

NxpHal: phNxpNciHal_deriveChipType Hw Version (0x68) Not Found: Setting Default Chip Type : PN548C2
NxpHal: phNxpNciHal_deriveChipType NxpNci > Product : PN548C2

Hope this helps.

UPDATE: Add relevant threads in linux-wireless mailing-list and patchwork

[1] https://patchwork.kernel.org/project/linux-wireless/list/?submitter=33142
[2] https://marc.info/?t=155740978400003&r=1&w=2
[3] https://marc.info/?t=155774435600001&r=1&w=2

@mweinelt
Copy link

Cool, I applied the patchset against Linux 5.1.2 and the nfc adapter on my X1 C6 came to live.

With nfctool --poll -d nfc0 it recognizes there is a token (tag0, tag1, ..., tagN), but there is little more information.

I have neard installed but it cannot currently find the default bluetooth adapter to pair a bluetooth headset, but at least it's trying to do that.

@ikelos
Copy link
Contributor

ikelos commented Dec 16, 2019

Hiya, I'm on kernel 5.4.3 (which definitely has the patchset changes, I've verified they're there manually) on a Lenovo T490. The following seem to be automatically loaded at boot:

Module                  Size  Used by
nxp_nci_i2c            16384  0
nxp_nci                16384  1 nxp_nci_i2c
nci                    45056  2 nxp_nci,nxp_nci_i2c
nfc                    86016  2 nci,nxp_nci

which suggests the device is being automatically detected, but I can't get nfctool, nfc-list or rfkill to list an adaptor, and nfctool --enable -d nfc0 gives no such device, so I'm not sure if I have all the necessary i2c modules loaded?

I have no unusual i2c devices listed under i2cdetect -l (notably, no Synopsys Designware entry):

i2c-3	unknown   	i915 gmbus dpd                  	N/A
i2c-1	unknown   	i915 gmbus dpc                  	N/A
i2c-6	unknown   	DPDDC-C                         	N/A
i2c-4	unknown   	DPDDC-A                         	N/A
i2c-2	unknown   	i915 gmbus misc                 	N/A
i2c-0	unknown   	i915 gmbus dpb                  	N/A
i2c-7	unknown   	SMBus I801 adapter at efa0      	N/A
i2c-5	unknown   	DPDDC-B                         	N/A

Only one contains an entry for 0x28, and it has entries for every value. It's also DPDDC-A which according to above comments is graphics related:

WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-4.
I will probe address range 0x03-0x77.
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 
70: 70 71 72 73 74 75 76 77   

The NXP-NCI demo app didn't work with the default configuration, but I also couldn't verify the demo app from the libnfc-nci project, but I wasn't sure what address or i2c bus to connect to, so that may not be surprising.

My DSDT also only lists 0x0000 for the various pin lists.

I'd very much like to help debug and get this working for everyone, since it seems a waste to have the hardware but not be able to use it. Please let me know if there's any additional information I can provide, or further testing I can run to try to figure out the issue...

@hsanjuan
Copy link

My NFC reader started working after upgrading the Synaptics/Fingerprint reader firmware (Prometheus). This is in lvfs-testing which needs to be enabled for fwupdmgr. After upgrading, the reader is now detected by nfctool (Kernel 5.4.6).

@hsanjuan
Copy link

More updates on my side (Lenovo X1 Carbon Gen 7). tl;dr: linux_libnfc-nci works!

The ACPI DSDT table is similar to the one posted above but addresses change:

        Device (NFC1)
        {
            Name (_ADR, Zero)  // _ADR: Address
            Name (_HID, "NXP1001")  // _HID: Hardware ID
            Name (_DDN, "NXP NFC For Win10")  // _DDN: DOS Device Name
            Name (_UID, One)  // _UID: Unique ID
            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
            {
                Name (RBUF, ResourceTemplate ()
                {
                    I2cSerialBusV2 (0x0029, ControllerInitiated, 0x00061A80,
                        AddressingMode7Bit, "\\_SB.PCI0.I2C0",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    GpioInt (Level, ActiveHigh, Exclusive, PullNone, 0x0000,
                        "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012A
                        }
                    GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x002F
                        }
                    GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0124
                        }
                })
                Return (RBUF) /* \_SB_.PCI0.I2C0.NFC1._CRS.RBUF */
            }

i2cdetect -l:

i2c-3   i2c             i915 gmbus dpd                          I2C adapter
i2c-1   i2c             i915 gmbus dpc                          I2C adapter
i2c-8   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-6   i2c             DPDDC-C                                 I2C adapter
i2c-4   i2c             DPDDC-A                                 I2C adapter
i2c-2   i2c             i915 gmbus misc                         I2C adapter
i2c-0   i2c             i915 gmbus dpb                          I2C adapter
i2c-9   smbus           SMBus I801 adapter at efa0              SMBus adapter
i2c-7   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-5   i2c             DPDDC-B                                 I2C adapter

This gives i2c-7 and i2c-8 as best candidates. But I also see /sys/bus/devices/i2c-NXP1001:00 which is a symlink to /sys/bus/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-NXP1001:00 so I guessed i2c-7 is the right bus.

I grabbed linux_libnfc-nci and compiled it (./configure --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64 --enable-alt) with the following in src/halimpl/pn54x/tml/i2c/phTmlNfc_alt.h:

#define I2C_BUS         "/dev/i2c-7"
#define I2C_ADDRESS     0x29
#define PIN_INT         200+0x12a
#define PIN_ENABLE      200+0x124

Where the bus is the one determined above, the I2C address comes from the DSDT, 200 is the offset from /sys/class/gpio/gpiochip200/base and the pins are from the DSDT.

Some people above reported some success at this point but my nfcDemoApp poll failed with Cannot select I2C address (Device or resource busy) (to see this I needed to enable debugging in /etc/libnfc-nxp-init.conf. I also noticed in the logs that it created pin gpio498 (PIN_INT) fine but it actually did not quite manage to create pin 492 (PIN_ENABLE) inside /sys/class/gpio/. If I manually ran echo 492 > /sys/class/gpio/export I also got echo: write error: Device or resource busy.

Doing cat /sys/kernel/debug/gpio actually showed that gpio492 is already registered. So someone was using it. It would seem this was the kernel module nxp_nci_i2c. I did modprobe -r nxp_nci_i2c and gpio492 got unregistered and the nfcDemoApp started working from that point. However, the nfc0 device dissapeared from rkill and neard/nfctool device list from that point.

I wonder if there is a way to get both a libnfc-nci program and rfkill co-exist. Pointers from here are appreciated!

@crosser
Copy link

crosser commented Jan 7, 2020

For anyone interested, I just uploaded the first version of my modified kernel driver: https://github.com/jr64/nxp-pn5xx

@jr64 first, I must report that the driver works on Thinkpad X1 Carbon Gen 7. Thanks for your work!
I have a couple of questions:

  1. Are there plans to upstream it (or is it already upstream)? I tested with 5.3.0, the kernel pn544 and nxp-nci_i2c do not work there.
  2. How to make smartcard tools (gnupg's scdaemon, pcscd and likes) see the reader?

@hsanjuan
Copy link

hsanjuan commented Jan 9, 2020

@crosser just two messages above I reported it working on 5.4.6 because it was upstreamed already.

@crosser
Copy link

crosser commented Jan 9, 2020

@hsanjuan Thanks! From the comment, it was not clear to me that you were using upstream module.

@ikelos
Copy link
Contributor

ikelos commented Jan 10, 2020

@hsanjuan Can you please provide a few more details? I got my fingerprint reader upgraded to the firmware from lvfs-testing (although fwupdmgr now isn't displaying it), and I'm on 5.4.10. I've got all the in-kernel nfc adaptors compiled as modules for testing, but can't find one that actually produces any dmesg output or anything that shows up in libnfc's nfc-list. As best I can tell, my device isn't accessible directly over I2C, but shows up in /sys as :acpi:NXP1001:.

Exactly which driver do you have loaded? Is it:

  • the official NXP one
  • the unofficial nxp-pn5xx
  • the kernel nxp_nci_i2c
  • the kernel pn544
  • some other module

@hsanjuan
Copy link

@hsanjuan Can you please provide a few more details? I got my fingerprint reader upgraded to the firmware from lvfs-testing (although fwupdmgr now isn't displaying it), and I'm on 5.4.10. I've got all the in-kernel nfc adaptors compiled as modules for testing, but can't find one that actually produces any dmesg output or anything that shows up in libnfc's nfc-list. As best I can tell, my device isn't accessible directly over I2C, but shows up in /sys as :acpi:NXP1001:.

Exactly which driver do you have loaded? Is it:

* the official NXP one

* the unofficial nxp-pn5xx

* the kernel nxp_nci_i2c

* the kernel pn544

* some other module

Does ncf0 show on the rfkill list or the nfctool -l list ?

My nfc/nxp/nci related modules:

nxp_nci_i2c            20480  0
nxp_nci                16384  1 nxp_nci_i2c
nci                    81920  2 nxp_nci,nxp_nci_i2c
nfc                   139264  14 nci,nxp_nci
rfkill                 28672  8 nfc,bluetooth,thinkpad_acpi,cfg80211

They all get loaded automatically, I did nothing special here and did not compile any extra modules. For reasons discussed above, libnfc tooling does not see it, but I could compile linux_libnfc-nci and make it see the reader (but I had to unload nxp_nci_i2c first). There's a single line in dmesg: nfc: nfc_init: NFC Core ver 0.1.

Mind that NFC needs to be enabled in the UEFI config (I had it disabled because it broke the touchpad before).

@dileks
Copy link

dileks commented Jan 10, 2020

Happy new 2020.

Wow, so many feedbacks :-).

Unfortunately, I have no more the Lenovo T470 notebook as I left the company.

Thanks for the hint with upgrading to a newer firmware via LVFS/testing.
Unfortunately, I had not that much luck getting LVFS running in sense of being able to upgrade any firmware specific stuff This was with Debian/testing AMD64. But that might be better supported theses days.
There was more firmware stuff available via LVFS than offered on the Lenovo support website (Windows binaries).

My last feedback from the Linux-kernel maintainers: The userspace tools seem to be a culprit to communicate with NFC device.

Happy testing and bonne chance folks.

Regards,

  • Sedat -

@ikelos
Copy link
Contributor

ikelos commented Jan 10, 2020

@hsanjuan Ok, so we must have different configurations (mine's detailed higher up). I do get those modules automatically loaded, but rfkill list does not mention NFC. I verified that NFC is enabled under security > I/O ports in my bios. I also get the NFC core line, but if that's the same as you then it's not all that informative. My rfkill list only returns the following:

0: phy0: Wireless LAN
	Soft blocked: no
	Hard blocked: no
1: tpacpi_bluetooth_sw: Bluetooth
	Soft blocked: no
	Hard blocked: no
2: hci0: Bluetooth
	Soft blocked: no
	Hard blocked: no

I haven't tried any non-kernel modules yet, so I haven't yet had the hardware working at all. What concerns me most is that I can't find the appropriate i2c bus in the list i2cdetect -l returns (see above for my full listing), and other than autoloading the nxp_nci_i2c module, there's no other mention of it in relation to i2c, only to acpi (which nxp-pn5xx mentions it should support). I guess trying the official NXP module or nxp-pn5xx will be my next step. Thanks for the clarification! 5:)

@hsanjuan
Copy link

hsanjuan commented Jan 10, 2020

@ikelos hmm, I'm on the Thinkpad X1 Carbon Gen 7.

While i2cdetect -l shows the Synopsys buses, i2cdetect is not able to find any devices when scanning them though, so it is of little help. I guess your device does not appear on /sys/bus/devices/i2c-NXP1001:00 either? And what does your acpi DSDT table show?

@pbirkants
Copy link

Hi!

I tried replicating the steps described by @hsanjuan on different hardware - Thinkpad X390 Yoga.

After compiling 5.4.8 kernel with upstream nxp_nci_i2c module enabled (current Debian default config does not include NCI modules) and adjusting the pin offsets according to my DSDT table, I could successfully run the various nfcDemoApp modes from linux_libnfc-nci without any extra steps.

The device also shows up in rfkill list and nfctool -l, but is not detected by nfc-scan-device -v -i. nfctool --enable -d nfc0 quits with a timeout, NFC: Read failed with error -121 (EREMOTEIO) is output in kernel log.

I looked around the sources for nfctool and the kernel drivers for this error, and it seems to me that powering on the reader fails.

@ikelos
Copy link
Contributor

ikelos commented Jan 10, 2020

@hsanjuan Hmmm, interesting to know the devices don't show up in i2cdetect, but given I don't have the buses it still suggests there's a difference.

Correct, there's no NXP1001:00 under i2c, only under acpi.

For the DSDT table, I tried to follow the instructions in the comment above:

plasma ~ # acpidump --output dsdt.aml           
Wrong checksum for FADT!

plasma ~ # acpixtract -a dsdt.aml    

Intel ACPI Component Architecture
ACPI Binary Table Extraction Utility version 20190703
Copyright (c) 2000 - 2019 Intel Corporation

  DSDT -  159706 bytes written (0x00026FDA) - dsdt.dat
  FACS -      64 bytes written (0x00000040) - facs.dat
  FACP -     244 bytes written (0x000000F4) - facp.dat
  SSDT -    6950 bytes written (0x00001B26) - ssdt1.dat
  SSDT -    1389 bytes written (0x0000056D) - ssdt2.dat
  SSDT -   15159 bytes written (0x00003B37) - ssdt3.dat
  SSDT -   12647 bytes written (0x00003167) - ssdt4.dat
  SSDT -    1554 bytes written (0x00000612) - ssdt5.dat
  TPM2 -      52 bytes written (0x00000034) - tpm2.dat
  UEFI -      66 bytes written (0x00000042) - uefi1.dat
  SSDT -    1328 bytes written (0x00000530) - ssdt6.dat
  HPET -      56 bytes written (0x00000038) - hpet.dat
  APIC -     300 bytes written (0x0000012C) - apic.dat
  MCFG -      60 bytes written (0x0000003C) - mcfg.dat
  ECDT -      83 bytes written (0x00000053) - ecdt.dat
  SSDT -    6802 bytes written (0x00001A92) - ssdt7.dat
  SSDT -    8949 bytes written (0x000022F5) - ssdt8.dat
  BOOT -      40 bytes written (0x00000028) - boot.dat
  SSDT -    3326 bytes written (0x00000CFE) - ssdt9.dat
  LPIT -     148 bytes written (0x00000094) - lpit.dat
  WSMT -      40 bytes written (0x00000028) - wsmt.dat
  SSDT -    5735 bytes written (0x00001667) - ssdt10.dat
  DBGP -      52 bytes written (0x00000034) - dbgp.dat
  DBG2 -      84 bytes written (0x00000054) - dbg2.dat
  MSDM -      85 bytes written (0x00000055) - msdm.dat
  BATB -      74 bytes written (0x0000004A) - batb.dat
  DMAR -     168 bytes written (0x000000A8) - dmar.dat
  NHLT -      45 bytes written (0x0000002D) - nhlt.dat
  FPDT -      68 bytes written (0x00000044) - fpdt.dat
  BGRT -      56 bytes written (0x00000038) - bgrt.dat
  UEFI -     298 bytes written (0x0000012A) - uefi2.dat
  XSDT -     268 bytes written (0x0000010C) - xsdt.dat
  RSDP -      36 bytes written (0x00000024) - rsdp.dat
  SSDT -    2736 bytes written (0x00000AB0) - ssdt11.dat
  SSDT -    1532 bytes written (0x000005FC) - ssdt12.dat
  SSDT -     329 bytes written (0x00000149) - ssdt13.dat
  SSDT -    1024 bytes written (0x00000400) - ssdt14.dat
  SSDT -     778 bytes written (0x0000030A) - ssdt15.dat
  SSDT -     791 bytes written (0x00000317) - ssdt16.dat
  SSDT -    1828 bytes written (0x00000724) - ssdt17.dat
  SSDT -    1470 bytes written (0x000005BE) - ssdt18.dat

plasma ~ # iasl -d dsdt.dat

Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20190703
Copyright (c) 2000 - 2019 Intel Corporation

File appears to be binary: found 46389 non-ASCII characters, disassembling
Binary file appears to be a valid ACPI table, disassembling
Input file dsdt.dat, Length 0x26FDA (159706) bytes
ACPI: DSDT 0x0000000000000000 026FDA (v02 LENOVO CFL      20170001 INTL 20160422)
Pass 1 parse of [DSDT]
Pass 2 parse of [DSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)

Parsing completed
ACPI Warning: NsLookup: Type mismatch on VEDI (RegionField), searching for (Buffer) (20190703/nsaccess-869)
ACPI Warning: NsLookup: Type mismatch on VEDI (RegionField), searching for (Buffer) (20190703/nsaccess-869)
ACPI Warning: NsLookup: Type mismatch on VEDI (RegionField), searching for (Buffer) (20190703/nsaccess-869)
Disassembly completed
ASL Output:    dsdt.dsl - 1081257 bytes
plasma ~ # iasl -tc dsdt.dsl

Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20190703
Copyright (c) 2000 - 2019 Intel Corporation

Compiler aborting due to parser-detected syntax error(s)
dsdt.dsl    472:     Name (SS4, One)
Error    6126 -        ^ syntax error, unexpected PARSEOP_NAME

ASL Input:     dsdt.dsl - Compilation aborted due to parser-detected syntax error(s)
Hex Dump:      dsdt.hex -     230 bytes

Compilation failed. 1 Errors, 0 Warnings, 0 Remarks
No AML files were generated due to syntax error(s)

So I'm guessing that's a problem? 5:S

In the dsl file there's a section that mentions the NXP, it was:

   Scope (\_SB.PCI0)
    {
        Name (RID, 0x00)
        Scope (I2C0)
        {
            Device (NFC1)
            {
                Name (_ADR, 0x00)  // _ADR: Address
                Name (_HID, "NXP1001")  // _HID: Hardware ID
                Name (_DDN, "NXP NFC For Win10")  // _DDN: DOS Device Name
                Name (_UID, 0x01)  // _UID: Unique ID
                Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                {
                    Name (RBUF, ResourceTemplate ()
                    {
                        I2cSerialBusV2 (0x0029, ControllerInitiated, 0x00061A80,
                            AddressingMode7Bit, "\\_SB.PCI0.I2C0",
                            0x00, ResourceConsumer, , Exclusive,
                            )
                        GpioInt (Level, ActiveHigh, Exclusive, PullNone, 0x0000,
                            "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer, ,
                            )
                            {   // Pin list
                                0x0000
                            }
                        GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
                            "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer, ,
                            )
                            {   // Pin list
                                0x0000
                            }
                        GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
                            "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer, ,
                            )
                            {   // Pin list
                                0x0000
                            }
                    })
                    CreateWordField (RBUF, 0x38, NFIP)
                    CreateWordField (RBUF, 0x60, NFEQ)
                    CreateWordField (RBUF, 0x88, NFON)
                    NFIP = GNUM (0x0404000A)
                    NFEQ = GNUM (0x0401000F)
                    NFON = GNUM (0x04040005)
                    Return (RBUF) /* \_SB_.PCI0.I2C0.NFC1._CRS.RBUF */
                }

                Method (_STA, 0, NotSerialized)  // _STA: Status
                {
                    If ((\OSYS >= 0x07DF))
                    {
                        If (((\_SB.GGIV (0x04030016) == 0x00) && (\NFCF == 0x00)))
                        {
                            Return (0x0F)
                        }
                    }

                    Return (0x00)
                }
            }
        }
    }

I guess the pin lists being 0x0000 is also a problem. I'm not sure where to go from here, any pointers would be greatly appreciated...

@dileks
Copy link

dileks commented Jan 11, 2020

Thanks @pbirkants

Just to clarify:
The default Debian/unstable Kernel v5.4.x does not ship the required kernel-modules and options. This is currently linux-image-5.4.0-2-amd64 (5.4.8-1).

Please, open a bug-report in Debian's BTS [1] that required kernel-modules and kernel-configs get enabled.

I would have said please concentrate on the Linux-upstream work and contact the appropriate maintainers [2], but Linux-NFC maintenance is currently marked "orphan" [3].

I am still confused which user-space tools is needed to get stuff run.

[1] https://www.debian.org/Bugs/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/MAINTAINERS
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/MAINTAINERS#n11627

@hsanjuan
Copy link

@ikelos the fact that the ports are 0x0000 does not look good though, perhaps someone on the internet has a decoded and posted a table with better values for your model? Maybe because ACPI is wrong, the kernel cannot find the device.... an alternative would be to try to get values from Windows if that's an option.

@maufl
Copy link

maufl commented Jun 23, 2020

I'm using Arch Linux on a T490. I had the kernel parameter apci_osi set to Linux because I experimented with bbswitch/bumblebee. I could not find the NFC reader, so I removed the parameter and now I'm able to find it :) Maybe that helps someone else.

@maufl
Copy link

maufl commented Jun 23, 2020

Well, I was not as successful as I hoped. It's enabled in the UEFI firmware, the kernel modules are loaded, rkfill does list it, nfctools does list it:

nfc0:
          Tags: [ ]
          Devices: [ ]
          Protocols: [ Felica MIFARE Jewel ISO-DEP NFC-DEP ]
          Powered: No
          RF Mode: None
          lto: 0
          rw: 0
          miux: 0

But powering on does not work:

» nfctool --enable --device=nfc0
Connection timed out

Also, nfc-list does not find it:

» nfc-list 
nfc-list uses libnfc 1.7.1
No NFC device found.

@0ln
Copy link

0ln commented Aug 15, 2020

I'm running Ubuntu 20.04.1 LTS and tried about everything discussed here on my X1 Carbon 7th gen.
Did anyone figure out a way to make NFC available and working for libnfc-powered tools (like mfoc and mfcuk)? That would be very interesting to see.

@Henrixounez
Copy link

Bump !
Is there any progress on this ?

@peterbabic
Copy link

I have just published a blog post about this topic.

A rough TLDR for Arch:

  1. install libnfc and pcslite and possibly ccid and opensc
  2. start pcscd.service from the pcslite mentioned above
  3. run nfc list to get the output:
nfc-list uses libnfc 1.8.0
NFC device: Alcor Micro AU9540 00 00 opened

Note that, I do not have the NFC module present on T470, only the smartcard module. These two both appear to be handled by Alcor AU9450.

@dileks
Copy link

dileks commented Apr 28, 2021

@peterbabic

Hey cool.
Thanks for the blog-post.

@JetseVerschuren
Copy link

Hi,

I'm trying to get the NFC reader in my T590 working. It is detected by rfkill

 % rfkill list nfc
0: nfc0: NFC
	Soft blocked: no
	Hard blocked: no

It's also detected by the system as I2C device

 % ls /sys/bus/i2c/devices/i2c-NXP1001:00/
driver  firmware_node  modalias  name  nfc  power  subsystem  uevent

And even by nfctool

% ./tools/nfctool/nfctool -l
nfc0:
          Tags: [ ]
          Devices: [ ]
          Protocols: [ Felica MIFARE Jewel ISO-DEP NFC-DEP ]
          Powered: No
          RF Mode: None
          lto: 0
          rw: 0
          miux: 0

But not by nfc-list (or any other libnfc application)

 % nfc-list   
No NFC device found.

Trying to enable the chip with nfctool (that does recognize it) unfortunately gives another error

 % ./tools/nfctool/nfctool -1 -d nfc0
Connection timed out

What can I do to get the chip working? I'd really love to get it working. I feel like I'm so close, yet so far away, especially 'cause I don't know why it is detected, but nothing more. Any help would be appreciated.

Thanks in advance,

Jetse

@arbv
Copy link

arbv commented Jul 14, 2022

@JetseVerschuren

The situation on my device is pretty similar to yours (HP ZBook Firefly G8), except that I can use it with nfctool (enable and sniff some data). Still, no luck with libnfc, though.

I think that libnfc should have a unified driver for NFC devices exposed via the netlink interface, just like this one. That would have a potential to support far more devices.

There was an issue regarding this (#466) but it was closed by @smortex, IMO, prematurely and for a wrong reason:

Closing since the point of libnfc is that it also work on non-Linux OSes

@albertodonato
Copy link

albertodonato commented Apr 8, 2023

I have a similar issue on a Thinkpad T14 Gen3 (Intel).

rfkill shows nfc0, but nfc-list doesn't find the device.

$ sudo i2cdetect -l
i2c-0   smbus           SMBus I801 adapter at efa0              SMBus adapter
i2c-1   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-2   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-3   i2c             i915 gmbus dpa                          I2C adapter
i2c-4   i2c             i915 gmbus dpb                          I2C adapter
i2c-5   i2c             i915 gmbus dpc                          I2C adapter
i2c-6   i2c             i915 gmbus tc1                          I2C adapter
i2c-7   i2c             i915 gmbus tc2                          I2C adapter
i2c-8   i2c             i915 gmbus tc3                          I2C adapter
i2c-9   i2c             i915 gmbus tc4                          I2C adapter
i2c-10  i2c             i915 gmbus tc5                          I2C adapter
i2c-11  i2c             i915 gmbus tc6                          I2C adapter
i2c-12  i2c             AUX A/DDI A/PHY A                       I2C adapter
i2c-13  i2c             AUX USBC1/DDI TC1/PHY TC1               I2C adapter
i2c-14  i2c             AUX USBC2/DDI TC2/PHY TC2               I2C adapter
i2c-15  i2c             AUX USBC3/DDI TC3/PHY TC3               I2C adapter
i2c-16  i2c             AUX USBC4/DDI TC4/PHY TC4               I2C adapter

From this it seems i2c-2 would be the bus in question as it has an NXP device:


$ ll /sys/bus/i2c/devices/
total 0
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-0 -> ../../../devices/pci0000:00/0000:00:1f.4/i2c-0/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-1 -> ../../../devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-1/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-10 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-10/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-11 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-11/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-12 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/i2c-12/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-13 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-1/i2c-13/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-14 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-2/i2c-14/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-15 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-3/i2c-15/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-16 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-4/i2c-16/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-2 -> ../../../devices/pci0000:00/0000:00:19.0/i2c_designware.1/i2c-2/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-3 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-3/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-4 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-4/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-5 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-5/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-6 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-6/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-7 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-7/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-8 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-8/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-9 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-9/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-ELAN0677:00 -> ../../../devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-1/i2c-ELAN0677:00/
lrwxrwxrwx 1 root root 0 Apr  7 23:02 i2c-NXP1001:00 -> ../../../devices/pci0000:00/0000:00:19.0/i2c_designware.1/i2c-2/i2c-NXP1001:00/

NFC-related drivers are loaded:

$ lsmod | grep nxp
nxp_nci_i2c            20480  0
nxp_nci                16384  1 nxp_nci_i2c
nci                    86016  2 nxp_nci,nxp_nci_i2c
nfc                   147456  2 nci,nxp_nci

@cluxter
Copy link

cluxter commented May 19, 2023

Same issue on a Lenovo ThinkPad T14 Gen 3 (Intel).
The OS is NixOS 22.11, Linux kernel v6.3.1 x86_64.

Here are some results:

# lsmod | grep nxp
nxp_nci_i2c            20480  0
nxp_nci                16384  1 nxp_nci_i2c
nci                    86016  2 nxp_nci,nxp_nci_i2c
nfc                   155648  2 nci,nxp_nci
i2c_core              131072  16 i2c_designware_platform,videodev,i2c_hid,i2c_designware_core,drm_kms_helper,intel_hid,i2c_algo_bit,drm_display_helper,i2c_smbus,thinkpad_acpi,i2c_i801,i2c_hid_acpi,i915,psmouse,nxp_nci_i2c,drm
# ll /sys/bus/i2c/devices/
total 0
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-0 -> ../../../devices/pci0000:00/0000:00:1f.4/i2c-0
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-1 -> ../../../devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-1
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-10 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-10
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-11 -> ../../../devices/pci0000:00/0000:00:19.0/i2c_designware.1/i2c-11
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-12 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/i2c-12
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-13 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-1/i2c-13
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-14 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-2/i2c-14
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-15 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-3/i2c-15
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-16 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-4/i2c-16
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-17 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-17
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-18 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-18
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-19 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-19
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-2 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-2
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-3 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-3
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-4 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-4
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-5 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-5
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-6 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-6
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-7 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-7
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-8 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-8
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-9 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-9
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-ELAN0677:00 -> ../../../devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-1/i2c-ELAN0677:00
lrwxrwxrwx 1 root root 0 mai   19 14:21 i2c-NXP1001:00 -> ../../../devices/pci0000:00/0000:00:19.0/i2c_designware.1/i2c-11/i2c-NXP1001:00
# rfkill
ID TYPE      DEVICE                  SOFT     HARD
 0 bluetooth tpacpi_bluetooth_sw débloqué débloqué
 1 bluetooth hci0                débloqué débloqué
 2 nfc       nfc0                débloqué débloqué
 3 wlan      phy0                débloqué débloqué
rfkill list nfc
2: nfc0: NFC
	Soft blocked: no
	Hard blocked: no
# i2cdetect -l

→ returns nothing.

# nfc-list
nfc-list uses libnfc 1.8.0
No NFC device found.
# nfctool -l
nfc0:
          Tags: [ ]
          Devices: [ ]
          Protocols: [ Felica MIFARE Jewel ISO-DEP NFC-DEP ]
          Powered: No
          RF Mode: None
          lto: 0
          rw: 0
          miux: 0

It seem that I'm able to power on the NFC module:

# nfctool --enable --device=nfc0
nfc0:
          Tags: [ ]
          Devices: [ ]
          Protocols: [ Felica MIFARE Jewel ISO-DEP NFC-DEP ]
          Powered: Yes
          RF Mode: None
          lto: 0
          rw: 0
          miux: 0

but this doesn't help anything:

# nfctool --device=nfc00 --set-param=lto=150,rw=1,miux=100
nfc0:
          Tags: [ ]
          Devices: [ ]
          Protocols: [ Felica MIFARE Jewel ISO-DEP NFC-DEP ]
          Powered: Yes
          RF Mode: None
          lto: 0
          rw: 0
          miux: 0

# nfctool -l
nfc0:
          Tags: [ ]
          Devices: [ ]
          Protocols: [ Felica MIFARE Jewel ISO-DEP NFC-DEP ]
          Powered: Yes
          RF Mode: None
          lto: 0
          rw: 0
          miux: 0

# nfc-list 
nfc-list uses libnfc 1.8.0
No NFC device found.

I've found in this document that the NFC module used on the Lenovo ThinkPad T14 Gen 3 (Intel) is the T77H747, which is the Foxconn NXP NPC3000 Module. See its datasheet here: https://fccid.io/MCLT77H747/User-Manual/User-Manual-rev-4-3127142

It seems that this module is not supported on libnfc yet.
Is there anything I could do to help having this device supported by libnfc?

EDIT: I opened my laptop to check and the NFC module is indeed the T77H747 as expected, it was written on the chip.

@multigiorgiplex
Copy link

I have the same issue with my Lenovo ThinkPad T590 (20N4)

Arch Linux, kernel 6.3.1-arch2-1 x86_64 , same lsmod, same device in the I2C bus, same rfkill from the previous messages of this thread.

I enable the device with nfctool I get:

# nfctool --device=nfc0 --enable 
Connection timed out

With

[ 931.301177] nxp-nci_i2c i2c-NXP1001:00: NFC: Read failed with error -121

in my dmesg.

Playing with the nxp_nci_i2c driver module I found out that a crude ~50ms delay before an I2C read makes me move on quite a bit.

This is my "debug" code of the function nxp_nci_i2c_nci_read() and nxp_nci_i2c_write() from drivers/nfc/nxp-nci/i2c.c

static int nxp_nci_i2c_write(void *phy_id, struct sk_buff *skb)
{
	int r;
	struct nxp_nci_i2c_phy *phy = phy_id;
	struct i2c_client *client = phy->i2c_dev;
	
	nfc_err(&client->dev, "nxp_nci_i2c_write\n");

	if (phy->hard_fault != 0)
		return phy->hard_fault;

	r = i2c_master_send(client, skb->data, skb->len);
	if (r < 0) {
		/* Retry, chip was in standby */
		msleep(110);
		r = i2c_master_send(client, skb->data, skb->len);
	}

	if (r < 0) {
		nfc_err(&client->dev, "Error %d on I2C send\n", r);
	} else if (r != skb->len) {
		nfc_err(&client->dev,
			"Invalid length sent: %u (expected %u)\n",
			r, skb->len);
		r = -EREMOTEIO;
	} else {
		/* Success but return 0 and not number of bytes */
		r = 0;
	}

	nfc_err(&client->dev, "nxp_nci_i2c_write: %d bytes\n", skb->len);
	
	return r;
}


static int nxp_nci_i2c_nci_read(struct nxp_nci_i2c_phy *phy,
				struct sk_buff **skb)
{
	struct nci_ctrl_hdr header; /* May actually be a data header */
	struct i2c_client *client = phy->i2c_dev;
	int r;
	
	usleep_range(50000, 55000);
	nfc_err(&client->dev, "nxp_nci_i2c_nci_read 0\n");


	r = i2c_master_recv(client, (u8 *) &header, NCI_CTRL_HDR_SIZE);
	if (r < 0) {
		goto nci_read_exit;
	} else if (r != NCI_CTRL_HDR_SIZE) {
		nfc_err(&client->dev, "Incorrect header length: %u\n", r);
		r = -EBADMSG;
		goto nci_read_exit;
	}

	*skb = alloc_skb(NCI_CTRL_HDR_SIZE + header.plen, GFP_KERNEL);
	if (*skb == NULL) {
		r = -ENOMEM;
		goto nci_read_exit;
	}

	skb_put_data(*skb, (void *)&header, NCI_CTRL_HDR_SIZE);

	if (!header.plen)
		return 0;
	
	nfc_err(&client->dev, "nxp_nci_i2c_nci_read 1\n");

	r = i2c_master_recv(client, skb_put(*skb, header.plen), header.plen);
	if (r < 0) {
		goto nci_read_exit_free_skb;
	} else if (r != header.plen) {
		nfc_err(&client->dev,
			"Invalid frame payload length: %u (expected %u)\n",
			r, header.plen);
		r = -EBADMSG;
		goto nci_read_exit_free_skb;
	}
	
	nfc_err(&client->dev, "nxp_nci_i2c_nci_read: read %d/%d bytes\n", r, header.plen);

	return 0;

nci_read_exit_free_skb:
	kfree_skb(*skb);
nci_read_exit:
	return r;
}

With the updated module loaded I get:

# nfctool --device=nfc0 --enable 
nfc0: 
         Tags: [ ] 
         Devices: [ ] 
         Protocols: [ Felica MIFARE Jewel ISO-DEP NFC-DEP ] 
         Powered: Yes 
         RF Mode: None 
         lto: 0 
         rw: 0 
         miux: 0 

With

[ 1719.430530] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_write 
[ 1719.430835] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_write: 4 bytes 
[ 1719.483423] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read 0 
[ 1719.483874] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read 1 
[ 1719.484182] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read: read 3/3 bytes 
[ 1719.484255] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_write 
[ 1719.484442] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_write: 3 bytes 
[ 1719.534238] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read 0 
[ 1719.534614] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read 1 
[ 1719.535574] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read: read 25/25 bytes 
[ 1719.535642] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_write 
[ 1719.535960] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_write: 10 bytes 
[ 1719.585590] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read 0 
[ 1719.585944] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read 1 
[ 1719.586254] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read: read 1/1 bytes 
[ 1719.636499] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_nci_read 0 
[ 1719.636696] nxp-nci_i2c i2c-NXP1001:00: NFC: Read failed with error -121

in the dmesg.

Polling results in a failure:

# nfctool --device=nfc0 --poll 
Connection timed out
[ 2030.451872] nxp-nci_i2c i2c-NXP1001:00: NFC: nxp_nci_i2c_write 
[ 2035.490724] nci: __nci_request: wait_for_completion_interruptible_timeout failed 0 
[ 2035.490730] nci: nci_start_poll: failed to set local general bytes 

It seems that the fourth read triggers -EREMOTEIO from the NCI header read.
I've tried to extend the read delay up to 5 seconds with no luck.

Could this be an issue with libnfc?
Can linux_libnfc-nci from NXP make the NFC work? (I've tried but not succeed yet)

@psy0p
Copy link

psy0p commented Jul 8, 2023

Hello everyone, nfctool works on my ThinkPad (L15) after patching the nxp-nci driver. Information about the patch can be found here:
https://patchwork.kernel.org/project/netdevbpf/patch/20230607170009.9458-3-giorgi.marco.96@disroot.org/

Maybe this will help some of you as well.
Best regards

@multigiorgiplex
Copy link

Nice to hear that, although that patch is a rough it makes the device working by checking the state of the IRQ GPIO prior reading.

Next step would be adding support for Linux NFC subsystem in libnfc, as mentioned in issue #674.

Marco

@fahlb
Copy link

fahlb commented Jan 31, 2024

I have the exact same situation as @JetseVerschuren, @albertodonato and @cluxter on my Lenovo ThinkPad X1 Yoga G7 with Fedora 39 and Kernel 6.6.13 . Even after enabling, nfc-list doesn't find any devices.

According to the linked document my device also features the T77H747 which would be called NPC300. It looks like it's also named NXP1001, like seen above.

$ ll /sys/bus/i2c/devices/ | grep "NXP"
lrwxrwxrwx. 1 root root 0 31. Jan 18:09 i2c-NXP1001:00 -> ../../../devices/pci0000:00/0000:00:19.0/i2c_designware.2/i2c-2/i2c-NXP1001:00

$ ll /sys/bus/i2c/devices/i2c-NXP1001\:00/
total 0
lrwxrwxrwx. 1 root root    0 31. Jan 18:09 driver -> ../../../../../../bus/i2c/drivers/nxp-nci_i2c
lrwxrwxrwx. 1 root root    0 31. Jan 22:22 firmware_node -> ../../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:3c/NXP1001:00
-r--r--r--. 1 root root 4096 31. Jan 22:22 modalias
-r--r--r--. 1 root root 4096 31. Jan 18:09 name
drwxr-xr-x. 3 root root    0 31. Jan 18:09 nfc
drwxr-xr-x. 2 root root    0 31. Jan 22:22 power
lrwxrwxrwx. 1 root root    0 31. Jan 18:09 subsystem -> ../../../../../../bus/i2c
-rw-r--r--. 1 root root 4096 31. Jan 18:09 uevent

$ cat /sys/bus/i2c/devices/i2c-NXP1001\:00/name
NXP1001:00

$ cat /sys/bus/i2c/devices/i2c-NXP1001\:00/uevent 
DRIVER=nxp-nci_i2c
MODALIAS=acpi:NXP1001:

However, I'm able to poll with nfctool

# nfctool --device=nfc0 --poll
Start polling on nfc0 as initiator

Targets found for nfc0
  Tags: [ tag1 ]
  Devices: [ ]

All this is with libnfc pcsc-lite and ccid installed and pcscd.service enabled.

$ sudo systemctl status pcscd.service 
● pcscd.service - PC/SC Smart Card Daemon
     Loaded: loaded (/usr/lib/systemd/system/pcscd.service; indirect; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Wed 2024-01-31 18:10:01 CET; 6h ago
TriggeredBy: ● pcscd.socket
       Docs: man:pcscd(8)
   Main PID: 2151 (pcscd)
      Tasks: 27 (limit: 38106)
     Memory: 5.9M
        CPU: 380ms
     CGroup: /system.slice/pcscd.service
             └─2151 /usr/sbin/pcscd --foreground --auto-exit

Jan 31 18:10:01 thinkpad systemd[1]: Started pcscd.service - PC/SC Smart Card Daemon.
Jan 31 18:10:01 thinkpad (pcscd)[2151]: pcscd.service: Referenced but unset environment v>
Jan 31 18:10:24 thinkpad pcscd[2151]: 00000000 auth.c:143:IsClientAuthorized() Process 26>
Jan 31 18:10:24 thinkpad pcscd[2151]: 00000292 winscard_svc.c:355:ContextThread() Rejecte>

pcsc_scan from https://github.com/LudovicRousseau/pcsc-tools doesn't find anything either:

$ pcsc_scan -r
No reader found.

I'm at a loss.

Also, #674 is closed without any pull request. Looks like nothing happened there.

@psy0p How did you verify that NFC is working? Maybe I'll try this patch in the future. For now I'm done with this. There seems to be little to no progress and I know too little to contribute in a meaningful way.

As a side note: After compiling https://github.com/NXPNFCLinux/linux_libnfc-nci, I get the following error with the nfcDemoApp.

$ ./nfcDemoApp poll
#########################################################################################
##                                       NFC demo                                      ##
#########################################################################################
##                                 Poll mode activated                                 ##
#########################################################################################
SNEP Client Register Callback Failed
Leaving ...

This might very well be because I didn't install the compiled drivers via make install. I didn't want to mess with that today. Documentation of https://github.com/NXPNFCLinux/linux_libnfc-nci are here

Interestingly, there is an open pull request over at NXPNFCLinux/linux_libnfc-nci#151, that claims to add support to my device but doesn't provide any additional information. As I understand this won't help with libnfc, anyway.

EDIT: Taking a closer look at NXPNFCLinux/linux_libnfc-nci#151, this appears to be similar to what @jr64 did here: #455 (comment). I bet the configuration to the i2c-2 bus is the solution to get the linux_libnfc-nci driver working. Maybe I'll give this a try. Not tonight, though...

Also, I found this test application: https://github.com/NXPNFCLinux/linux_NfcFactoryTestApp. Again, not tested yet but maybe I'll give this a second look in the future.

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

No branches or pull requests