From 0f98b3382b8ff78b2ade67397d6aef6f3ecfb864 Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Wed, 1 Oct 2025 09:34:31 +0200 Subject: [PATCH 1/3] A few fixes for RPiOS Debian Bookworm 2025.05.13 --- Makefile | 24 ++++++++++- README.md | 108 +++++++++++++++++++++++++++++++++++++++++++++++++- nfc/common.c | 2 +- nfc/common.h | 2 + nfc/i2c_drv.c | 13 +++--- nfc/i2c_drv.h | 5 +-- 6 files changed, 139 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 2a33c73..e4a3c5d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,26 @@ # # Makefile for the kernel nfc device drivers. +# Building I2C version only for aarch64 # -obj-y += nfc/ + +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) + +all: modules + +modules: + $(MAKE) -C $(KDIR) M=$(PWD) modules + +clean: + $(MAKE) -C $(KDIR) M=$(PWD) clean + +install: + $(MAKE) -C $(KDIR) M=$(PWD) modules_install + +# Module configuration +obj-m += nxpnfc_i2c.o +nxpnfc_i2c-objs := nfc/common.o nfc/i2c_drv.o + +# Enable I2C configuration +ccflags-y += -DCONFIG_NXP_NFC_I2C=1 +ccflags-y += -Infc/ diff --git a/README.md b/README.md index a8c9ef2..df77f8b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,106 @@ -# nxpnfc -PN7160 NFC Open Source Kernel mode driver supporting both I²C and SPI interfaces \ No newline at end of file +# NXP NFC Kernel Driver + +This repository contains the NXP NFC kernel driver for PN7160 and compatible NFC controllers, specifically configured for Raspberry Pi aarch64 systems. + +## Features + +- **I2C Interface Support**: Optimized for I2C communication with NFC controllers +- **PN7160 Compatible**: Tested with NXP PN7160 NFC controller +- **Raspberry Pi Support**: Built and tested on Raspberry Pi CM4 with aarch64 architecture +- **Device Tree Integration**: Includes device tree overlay for automatic hardware detection +- **Auto-loading**: Configured for automatic module and overlay loading at boot + +## Hardware Requirements + +- Raspberry Pi with aarch64 architecture (tested on CM4) +- NXP PN7160 NFC controller board +- I2C connection (SDA/SCL) +- GPIO pins for IRQ, VEN, and optionally FW_DWL + +## Quick Start + +### 1. Build the Kernel Module + +```bash +make clean +make +``` + +### 2. Install the Module and Overlay + +```bash +sudo make install +sudo cp pn7160-overlay.dtbo /boot/firmware/overlays/ +``` + +### 3. Configure Boot Loading + +Add to `/boot/firmware/config.txt`: +``` +dtparam=i2c_arm=on +dtoverlay=pn7160-overlay +``` + +Add to `/etc/modules`: +``` +nxpnfc_i2c +``` + +### 4. Connect Hardware + +Connect your PN7160 according to the pin configuration in the setup guide. + +### 5. Reboot and Test + +```bash +sudo reboot +# After reboot: +lsmod | grep nxpnfc +ls -la /dev/nxpnfc* +i2cdetect -y 1 +``` + +## Documentation + +- **[PN7160_SETUP_GUIDE.md](PN7160_SETUP_GUIDE.md)**: Complete setup and troubleshooting guide +- **[AN13287.pdf](AN13287.pdf)**: NXP application note (if available) + +## Repository Structure + +``` +├── nfc/ # Kernel module source code +│ ├── common.c # Common NFC functionality +│ ├── common.h # Common header definitions +│ ├── i2c_drv.c # I2C driver implementation +│ ├── i2c_drv.h # I2C driver header +│ ├── spi_drv.c # SPI driver (reference) +│ ├── spi_drv.h # SPI driver header (reference) +│ └── Makefile # NFC module Makefile +├── pn7160-overlay.dts # Device tree overlay source +├── Makefile # Main build configuration +├── Kconfig # Kernel configuration options +├── PN7160_SETUP_GUIDE.md # Detailed setup documentation +└── README.md # This file +``` + +## Supported Hardware + +- **Primary**: NXP PN7160 NFC controller +- **Architecture**: ARM aarch64 (Raspberry Pi CM4) +- **Kernel**: 6.12.47+rpt-rpi-v8 (and compatible versions) + +## License + +GPL v2 - See [LICENSE](LICENSE) file for details. + +## Contributing + +This is part of the NXPNFCLinux project. Please ensure all changes maintain compatibility with the existing NXP NFC software stack. + +## Troubleshooting + +See [PN7160_SETUP_GUIDE.md](PN7160_SETUP_GUIDE.md) for detailed troubleshooting steps. + +## Character Device + +Once loaded successfully, the driver creates `/dev/nxpnfc` which can be used by userspace NFC applications. \ No newline at end of file diff --git a/nfc/common.c b/nfc/common.c index 0a305b7..f69d8f7 100755 --- a/nfc/common.c +++ b/nfc/common.c @@ -183,7 +183,7 @@ int nfc_misc_register(struct nfc_dev *nfc_dev, ret); return ret; } - nfc_dev->nfc_class = class_create(THIS_MODULE, classname); + nfc_dev->nfc_class = class_create(classname); if (IS_ERR(nfc_dev->nfc_class)) { ret = PTR_ERR(nfc_dev->nfc_class); pr_err("%s: failed to register device class ret %d\n", __func__, diff --git a/nfc/common.h b/nfc/common.h index 678177b..8c695ab 100755 --- a/nfc/common.h +++ b/nfc/common.h @@ -205,4 +205,6 @@ int configure_gpio(unsigned int gpio, int flag); void gpio_set_ven(struct nfc_dev *nfc_dev, int value); void gpio_free_all(struct nfc_dev *nfc_dev); int validate_nfc_state_nci(struct nfc_dev *nfc_dev); +void set_valid_gpio(int gpio, int value); +int get_valid_gpio(int gpio); #endif /* _COMMON_H_ */ diff --git a/nfc/i2c_drv.c b/nfc/i2c_drv.c index 350609e..7e87794 100755 --- a/nfc/i2c_drv.c +++ b/nfc/i2c_drv.c @@ -259,7 +259,7 @@ ssize_t nfc_i2c_dev_write(struct file *filp, const char __user *buf, static const struct file_operations nfc_i2c_dev_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, + .llseek = noop_llseek, .read = nfc_i2c_dev_read, .write = nfc_i2c_dev_write, .open = nfc_dev_open, @@ -267,7 +267,7 @@ static const struct file_operations nfc_i2c_dev_fops = { .unlocked_ioctl = nfc_dev_ioctl, }; -int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) +int nfc_i2c_dev_probe(struct i2c_client *client) { int ret = 0; struct nfc_dev *nfc_dev = NULL; @@ -384,21 +384,19 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) return ret; } -int nfc_i2c_dev_remove(struct i2c_client *client) +void nfc_i2c_dev_remove(struct i2c_client *client) { - int ret = 0; struct nfc_dev *nfc_dev = NULL; pr_info("%s: remove device\n", __func__); nfc_dev = i2c_get_clientdata(client); if (!nfc_dev) { pr_err("%s: device doesn't exist anymore\n", __func__); - ret = -ENODEV; - return ret; + return; } if (nfc_dev->dev_ref_count > 0) { pr_err("%s: device already in use\n", __func__); - return -EBUSY; + return; } device_init_wakeup(&client->dev, false); free_irq(client->irq, nfc_dev); @@ -409,7 +407,6 @@ int nfc_i2c_dev_remove(struct i2c_client *client) kfree(nfc_dev->read_kbuf); kfree(nfc_dev->write_kbuf); kfree(nfc_dev); - return ret; } int nfc_i2c_dev_suspend(struct device *device) diff --git a/nfc/i2c_drv.h b/nfc/i2c_drv.h index b6b4910..7bbab7a 100755 --- a/nfc/i2c_drv.h +++ b/nfc/i2c_drv.h @@ -37,9 +37,8 @@ struct i2c_dev { }; long nfc_i2c_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg); -int nfc_i2c_dev_probe(struct i2c_client *client, - const struct i2c_device_id *id); -int nfc_i2c_dev_remove(struct i2c_client *client); +int nfc_i2c_dev_probe(struct i2c_client *client); +void nfc_i2c_dev_remove(struct i2c_client *client); int nfc_i2c_dev_suspend(struct device *device); int nfc_i2c_dev_resume(struct device *device); From 84ac2506aedec9abc42d1408560b76e1aa202417 Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Wed, 1 Oct 2025 09:45:38 +0200 Subject: [PATCH 2/3] Added device tree overlay file --- .gitignore | 26 +++++ PN7160_SETUP_GUIDE.md | 248 ++++++++++++++++++++++++++++++++++++++++++ pn7160-overlay.dts | 47 ++++++++ 3 files changed, 321 insertions(+) create mode 100644 .gitignore create mode 100644 PN7160_SETUP_GUIDE.md create mode 100644 pn7160-overlay.dts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fdfa108 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Build artifacts +*.ko +*.o +*.mod +*.mod.c +.*.cmd +modules.order +Module.symvers +.tmp_versions/ + +# Device tree compiled files +*.dtbo + +# Temporary files +.lgd-nfy* +*~ +*.swp +*.swo + +# Editor files +.vscode/ +.idea/ + +# Backup files +*.backup +*.bak \ No newline at end of file diff --git a/PN7160_SETUP_GUIDE.md b/PN7160_SETUP_GUIDE.md new file mode 100644 index 0000000..94b1bb2 --- /dev/null +++ b/PN7160_SETUP_GUIDE.md @@ -0,0 +1,248 @@ +# PN7160 NFC Setup Documentation + +## Overview +This document describes the complete setup for the NXP PN7160 NFC controller on Raspberry Pi CM4 with automatic kernel module loading. + +## Hardware Configuration + +### I2C Connection (Default: I2C1) +- **SDA**: GPIO2 (Pin 3) +- **SCL**: GPIO3 (Pin 5) +- **VCC**: 3.3V (Pin 1 or 17) +- **GND**: Ground (Pin 6, 9, 14, 20, 25, 30, 34, or 39) + +### GPIO Pins Used +- **IRQ (Interrupt)**: GPIO23 (Pin 16) +- **VEN (Voltage Enable)**: GPIO24 (Pin 18) +- **FW_DWL (Firmware Download)**: GPIO25 (Pin 22) - Optional + +### I2C Address +- **Default**: 0x28 (40 decimal) + +## Files Created/Modified + +### Device Tree Overlay +- **Source**: `/home/alex/nxpnfc/pn7160-overlay.dts` +- **Compiled**: `/boot/firmware/overlays/pn7160-overlay.dtbo` + +### Kernel Module +- **Source**: `/home/alex/nxpnfc/nfc/` +- **Built**: `/home/alex/nxpnfc/nxpnfc_i2c.ko` +- **Installed**: `/lib/modules/6.12.47+rpt-rpi-v8/updates/nxpnfc_i2c.ko.xz` + +### Configuration Files Modified +- **`/boot/firmware/config.txt`**: Added overlay and enabled I2C +- **`/etc/modules`**: Added auto-loading of nxpnfc_i2c module + +## Build Process + +### Building the Kernel Module +```bash +cd /home/alex/nxpnfc +make clean +make +``` + +### Compiling Device Tree Overlay +```bash +dtc -@ -I dts -O dtb -o pn7160-overlay.dtbo pn7160-overlay.dts +``` + +### Installation +```bash +# Install kernel module +sudo make install +sudo depmod -a + +# Install device tree overlay +sudo cp pn7160-overlay.dtbo /boot/firmware/overlays/ + +# Add to auto-load modules +echo "nxpnfc_i2c" | sudo tee -a /etc/modules + +# Set up device permissions for user access +echo 'KERNEL=="nxpnfc", MODE="0666", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/99-nxpnfc.rules +sudo udevadm control --reload-rules +``` + +## Configuration Details + +### config.txt Additions +``` +dtparam=i2c_arm=on +dtoverlay=pn7160-overlay +``` + +### Important Device Tree Properties +The overlay uses specific NXP property names (critical for proper operation): +- `nxp,nxpnfc-irq` - IRQ GPIO pin +- `nxp,nxpnfc-ven` - VEN GPIO pin +- `nxp,nxpnfc-fw-dwnld` - Firmware download GPIO pin + +### Overlay Parameters (Optional Customization) +You can customize GPIO pins by using parameters: +``` +dtoverlay=pn7160-overlay,irq_pin=23,ven_pin=24,fw_dnld_pin=25,i2c_address=0x28 +``` + +### Successful Probe Messages +When working correctly, you should see these kernel messages: +``` +nfc_parse_dt: irq 536 +nfc_parse_dt: 536, 537, 535 +nfc_i2c_dev_probe: requesting IRQ 55 +nfc_i2c_dev_probe: probing nfc i2c successfully +``` + +## Testing and Verification + +### After Reboot, Check: + +1. **I2C Bus Detection**: + ```bash + i2cdetect -l + i2cdetect -y 1 + ``` + +2. **Module Loading**: + ```bash + lsmod | grep nxpnfc + ``` + +3. **Device Detection**: + ```bash + ls -la /dev/nxpnfc* + # Should show: crw-rw-rw- 1 root root 239, 0 /dev/nxpnfc + ``` + +4. **Kernel Messages**: + ```bash + dmesg | grep -i nfc + ``` + +5. **Device Tree Info**: + ```bash + ls /proc/device-tree/soc/i2c@7e804000/ + ``` + +6. **Verify Working Setup**: + ```bash + # Should show UU at address 0x28 + i2cdetect -y 1 + + # Should show pn7160-overlay + sudo dtoverlay -l + + # Should show character device + ls -la /dev/nxpnfc* + + # Should show successful probe messages + dmesg | grep "probing nfc i2c successfully" + ``` + +## Troubleshooting + +### Common Issues: + +1. **No /dev/nxpnfc device**: + - Check hardware connections + - Verify I2C address with `i2cdetect -y 1` (should show "UU" at 0x28) + - Check GPIO pin connections + - Verify overlay is loaded: `sudo dtoverlay -l` + +2. **Module not loading**: + - Check `dmesg` for errors + - Verify module is in `/lib/modules/$(uname -r)/updates/` + - Try manual loading: `sudo modprobe nxpnfc_i2c` + +3. **GPIO parsing errors (irq gpio invalid -2)**: + - This indicates incorrect device tree property names + - Ensure overlay uses `nxp,nxpnfc-irq` (not `irq-gpio`) + - Recompile and reinstall overlay if modified + +4. **I2C communication errors**: + - Verify pull-up resistors on SDA/SCL (usually 4.7kΩ) + - Check power supply (3.3V) + - Verify ground connections + - Ensure I2C is enabled: `dtparam=i2c_arm=on` + +5. **Overlay not loading at boot**: + - Check `/boot/firmware/config.txt` for `dtoverlay=pn7160-overlay` + - Verify overlay file exists: `/boot/firmware/overlays/pn7160-overlay.dtbo` + - Check for syntax errors in config.txt + +6. **Permission denied accessing /dev/nxpnfc**: + - Verify udev rules: `cat /etc/udev/rules.d/99-nxpnfc.rules` + - Check device permissions: `ls -la /dev/nxpnfc` + - Should show mode 0666 (crw-rw-rw-) + - Reload udev rules: `sudo udevadm control --reload-rules` + - Replug device or reboot if needed + +### Manual Commands: + +```bash +# Reload module manually +sudo rmmod nxpnfc_i2c +sudo modprobe nxpnfc_i2c + +# Check overlay loading +sudo dtoverlay -l + +# Load overlay manually (for testing) +sudo dtoverlay pn7160-overlay + +# Remove overlay manually (for testing) +sudo dtoverlay -r pn7160-overlay + +# Scan I2C bus (should show "UU" at 0x28 when working) +i2cdetect -y 1 + +# Check device tree properties +ls /proc/device-tree/soc/i2c@7e804000/pn7160@28/ + +# Check GPIO usage +sudo cat /sys/kernel/debug/gpio +``` + +## Hardware Setup Checklist + +- [ ] PN7160 connected to 3.3V power +- [ ] Ground connections secure +- [ ] SDA connected to GPIO2 +- [ ] SCL connected to GPIO3 +- [ ] IRQ connected to GPIO23 +- [ ] VEN connected to GPIO24 +- [ ] FW_DWL connected to GPIO25 (if used) +- [ ] Pull-up resistors on I2C lines (if not on board) + +## Next Steps + +1. **Reboot the system** for all changes to take effect +2. **Connect PN7160 hardware** according to the pin configuration +3. **Test NFC functionality** using appropriate user-space libraries +4. **Develop applications** using the `/dev/nxpnfc` character device + +## User Space Applications + +Popular NFC libraries that work with this setup: +- **libnfc**: Open-source NFC library +- **NXP NFC Stack**: Official NXP software +- **Custom applications**: Direct character device access + +## Notes + +- The device tree overlay supports parameter customization for different GPIO configurations +- The kernel module is built for kernel version 6.12.47+rpt-rpi-v8 (aarch64 architecture) +- Code has been updated for newer kernel API compatibility (class_create, I2C driver signatures) +- All configuration persists across reboots +- Backup of original config.txt saved as `/boot/firmware/config.txt.backup` +- GPIO numbers in Linux are offset: GPIO24 = linux gpio-536 (512+24) +- The module creates `/dev/nxpnfc` character device with major number 236 + +## Architecture Requirements + +- **Platform**: Raspberry Pi CM4 (or compatible aarch64 Raspberry Pi) +- **Kernel**: 6.12.x series (tested on 6.12.47+rpt-rpi-v8) +- **Architecture**: ARM aarch64 +- **I2C**: Hardware I2C1 bus (GPIO2/GPIO3) +- **Compiler**: GCC 12.2.0 (or compatible) \ No newline at end of file diff --git a/pn7160-overlay.dts b/pn7160-overlay.dts new file mode 100644 index 0000000..f6f5027 --- /dev/null +++ b/pn7160-overlay.dts @@ -0,0 +1,47 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pn7160: pn7160@28 { + compatible = "nxp,nxpnfc"; + reg = <0x28>; + interrupt-parent = <&gpio>; + interrupts = <23 2>; /* GPIO23, IRQ_TYPE_EDGE_FALLING */ + nxp,nxpnfc-irq = <&gpio 23 0>; + nxp,nxpnfc-ven = <&gpio 24 0>; + nxp,nxpnfc-fw-dwnld = <&gpio 25 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pn7160_pins>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + pn7160_pins: pn7160_pins { + brcm,pins = <23 24 25>; + brcm,function = <0 1 0>; /* input, output, input */ + brcm,pull = <2 0 0>; /* pull-up, no pull, no pull */ + }; + }; + }; + + __overrides__ { + i2c_address = <&pn7160>, "reg:0"; + irq_pin = <&pn7160>, "nxp,nxpnfc-irq:4", + <&pn7160>, "interrupts:0"; + ven_pin = <&pn7160>, "nxp,nxpnfc-ven:4"; + fw_dnld_pin = <&pn7160>, "nxp,nxpnfc-fw-dwnld:4"; + }; +}; \ No newline at end of file From bad4414ceda2920a0f1c835f59e46cb270b24f08 Mon Sep 17 00:00:00 2001 From: Alex Hoffmann Date: Wed, 1 Oct 2025 09:57:42 +0200 Subject: [PATCH 3/3] Updated README.md --- README.md | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index df77f8b..0d03ac5 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ ls -la /dev/nxpnfc* i2cdetect -y 1 ``` +Once loaded successfully, the driver creates `/dev/nxpnfc` which can be used by userspace NFC applications. + ## Documentation - **[PN7160_SETUP_GUIDE.md](PN7160_SETUP_GUIDE.md)**: Complete setup and troubleshooting guide @@ -68,15 +70,15 @@ i2cdetect -y 1 ## Repository Structure ``` -├── nfc/ # Kernel module source code -│ ├── common.c # Common NFC functionality -│ ├── common.h # Common header definitions +├── nfc/ # Kernel module source code +│ ├── common.c # Common NFC functionality +│ ├── common.h # Common header definitions │ ├── i2c_drv.c # I2C driver implementation │ ├── i2c_drv.h # I2C driver header │ ├── spi_drv.c # SPI driver (reference) │ ├── spi_drv.h # SPI driver header (reference) │ └── Makefile # NFC module Makefile -├── pn7160-overlay.dts # Device tree overlay source +├── pn7160-overlay.dts # Device tree overlay source ├── Makefile # Main build configuration ├── Kconfig # Kernel configuration options ├── PN7160_SETUP_GUIDE.md # Detailed setup documentation @@ -89,18 +91,7 @@ i2cdetect -y 1 - **Architecture**: ARM aarch64 (Raspberry Pi CM4) - **Kernel**: 6.12.47+rpt-rpi-v8 (and compatible versions) -## License - -GPL v2 - See [LICENSE](LICENSE) file for details. - -## Contributing - -This is part of the NXPNFCLinux project. Please ensure all changes maintain compatibility with the existing NXP NFC software stack. - ## Troubleshooting See [PN7160_SETUP_GUIDE.md](PN7160_SETUP_GUIDE.md) for detailed troubleshooting steps. -## Character Device - -Once loaded successfully, the driver creates `/dev/nxpnfc` which can be used by userspace NFC applications. \ No newline at end of file