at 25.11-pre 7.9 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.hardware.nfc-nci; 10 11 # To understand these settings in more detail, refer to the upstream configuration templates 12 # available at https://github.com/NXPNFCLinux/linux_libnfc-nci/tree/master/conf . 13 # Settings in curly braces are NCI commands, the "NFC Controller Interface Specification" 14 # as well as the "NFC Digital Protocol Technical Specification" can be found online. 15 # These default settings have been specifically engineered for the Lenovo NXP1001 (NPC300) chipset. 16 defaultSettings = { 17 # This block will be emitted into /etc/libnfc-nci.conf 18 nci = { 19 # Set up general logging 20 APPL_TRACE_LEVEL = "0x01"; 21 PROTOCOL_TRACE_LEVEL = "0x01"; 22 # Set up which NFC technologies are enabled (due to e.g. local regulation or patent law) 23 HOST_LISTEN_TECH_MASK = "0x07"; 24 POLLING_TECH_MASK = "0xEF"; 25 P2P_LISTEN_TECH_MASK = "0xC5"; 26 }; 27 # This block will be emitted into /etc/libnfc-nxp-init.conf 28 init = { 29 # Setup logging of the individual userland library components 30 NXPLOG_GLOBAL_LOGLEVEL = "0x01"; 31 NXPLOG_EXTNS_LOGLEVEL = "0x01"; 32 NXPLOG_NCIHAL_LOGLEVEL = "0x01"; 33 NXPLOG_NCIX_LOGLEVEL = "0x01"; 34 NXPLOG_NCIR_LOGLEVEL = "0x01"; 35 NXPLOG_FWDNLD_LOGLEVEL = "0x00"; 36 NXPLOG_TML_LOGLEVEL = "0x01"; 37 # Where to find the kernel device node 38 NXP_NFC_DEV_NODE = ''"/dev/pn544"''; 39 # Enable the NXP proprietary features of the chip 40 NXP_ACT_PROP_EXTN = "{2F, 02, 00}"; 41 # Configure the NFC Forum profile: 42 # 0xA0 0x44: POLL_PROFILE_SEL_CFG = 0x00 (Use NFC Forum profile default configuration values. Specifically, not EMVCo.) 43 NXP_NFC_PROFILE_EXTN = '' 44 {20, 02, 05, 01, 45 A0, 44, 01, 00 46 } 47 ''; 48 # Enable chip standby mode 49 NXP_CORE_STANDBY = "{2F, 00, 01, 01}"; 50 # Enable NCI packet fragmentation on the I2C bus 51 NXP_I2C_FRAGMENTATION_ENABLED = "0x01"; 52 }; 53 # This block will be emitted into /etc/libnfc-nxp-pn547.conf as well as /etc/libnfc-nxp-pn548.conf 54 # Which file is actually used is decided by the library at runtime depending on chip variant, both files are required. 55 pn54x = { 56 # Enable Mifare Classic reader functionality 57 MIFARE_READER_ENABLE = "0x01"; 58 # Configure clock source - use XTAL (hardware crystal) instead of PLL (synthetic clock) 59 NXP_SYS_CLK_SRC_SEL = "0x01"; 60 NXP_SYS_CLK_FREQ_SEL = "0x00"; 61 NXP_SYS_CLOCK_TO_CFG = "0x01"; 62 # Configure the non-propriety NCI settings in EEPROM: 63 # 0x28: PN_NFC_DEP_SPEED = 0x00 (Data exchange: Highest Available Bit Rates) 64 # 0x21: PI_BIT_RATE = 0x00 (Maximum allowed bit rate: 106 Kbit/s) 65 # 0x30: LA_BIT_FRAME_SDD = 0x08 (Bit Frame SDD value to be sent in Byte 1 of SENS_RES) 66 # 0x31: LA_PLATFORM_CONFIG = 0x03 (Platform Configuration value to be sent in Byte 2 of SENS_RES) 67 # 0x33: LA_NFCID1 = [ 0x04 0x03 0x02 0x01 ] ("Unique" NFCID1 ID in SENS_RES) 68 # 0x54: LF_CON_BITR_F = 0x06 (Bit rates to listen for: Both) 69 # 0x50: LF_PROTOCOL_TYPE = 0x02 (Protocols supported in Listen Mode for NFC-F: NFC-DEP) 70 # 0x5B: LI_BIT_RATE = 0x00 (Maximum supported bit rate: 106 Kbit/s) 71 # 0x60: LN_WT = 0x0E (Waiting Time NFC-DEP WT_MAX default for Initiator) 72 # 0x80: RF_FIELD_INFO = 0x01 (Chip is allowed to emit RF Field Information Notifications) 73 # 0x81: RF_NFCEE_ACTION = 0x01 (Chip should send trigger notification for the default set of NFCEE actions) 74 # 0x82: NFCDEP_OP = 0x0E (NFC-DEP protocol behavior: Default flags, but also enable RTOX requests) 75 # 0x18: PF_BIT_RATE = 0x01 (NFC-F discovery polling initial bit rate: 106 Kbit/s) 76 NXP_CORE_CONF = '' 77 {20, 02, 2B, 0D, 78 28, 01, 00, 79 21, 01, 00, 80 30, 01, 08, 81 31, 01, 03, 82 33, 04, 04, 03, 02, 01, 83 54, 01, 06, 84 50, 01, 02, 85 5B, 01, 00, 86 60, 01, 0E, 87 80, 01, 01, 88 81, 01, 01, 89 82, 01, 0E, 90 18, 01, 01 91 } 92 ''; 93 # Configure the proprietary NXP extension to the NCI standard in EEPROM: 94 # 0xA0 0x5E: JEWEL_RID_CFG = 0x01 (Enable sending RID to T1T on RF) 95 # 0xA0 0x40: TAG_DETECTOR_CFG = 0x00 (Tag detector: Disable both AGC based detection and trace mode) 96 # 0xA0 0x43: TAG_DETECTOR_FALLBACK_CNT_CFG = 0x00 (Tag detector: Disable hybrid mode, only use LPCD to initiate polling) 97 # 0xA0 0x0F: DH_EEPROM_AREA_1 = [ 32 bytes of opaque Lenovo data ] (Custom configuration for the Lenovo customized chip firmware) 98 # See also https://github.com/nfc-tools/libnfc/issues/455#issuecomment-2221979571 99 NXP_CORE_CONF_EXTN = '' 100 {20, 02, 30, 04, 101 A0, 5E, 01, 01, 102 A0, 40, 01, 00, 103 A0, 43, 01, 00, 104 A0, 0F, 20, 105 00, 03, 1D, 01, 03, 00, 02, 00, 106 01, 00, 01, 00, 00, 00, 00, 00, 107 00, 00, 00, 00, 00, 00, 00, 00, 108 00, 00, 00, 00, 00, 00, 00, 00 109 } 110 ''; 111 # Firmware-specific protocol configuration parameters (one byte per protocol) 112 NXP_NFC_PROPRIETARY_CFG = "{05:FF:FF:06:81:80:70:FF:FF}"; 113 # Configure power supply of chip, use Lenovo driver configuration, which deviates a bit from the spec: 114 # 0xA0 0x0E: PMU_CFG = [ 0x16, 0x09, 0x00 ] (VBAT1 connected to 5V, TVDD monitoring: 3.6V, TxLDO Voltage in reader and card mode: 3.3V) 115 NXP_EXT_TVDD_CFG = "0x01"; 116 NXP_EXT_TVDD_CFG_1 = '' 117 {20, 02, 07, 01, 118 A0, 0E, 03, 16, 09, 00 119 } 120 ''; 121 # Use the default for NFA_EE_MAX_EE_SUPPORTED stack size (concerns HCI) 122 NXP_NFC_MAX_EE_SUPPORTED = "0x00"; 123 }; 124 }; 125 126 generateSettings = 127 cfgName: 128 let 129 toKeyValueLines = 130 obj: builtins.concatStringsSep "\n" (map (key: "${key}=${obj.${key}}") (builtins.attrNames obj)); 131 in 132 toKeyValueLines (defaultSettings.${cfgName} // (cfg.settings.${cfgName} or { })); 133in 134{ 135 options.hardware.nfc-nci = { 136 enable = lib.mkEnableOption "PN5xx kernel module with udev rules, libnfc-nci userland, and optional ifdnfc-nci PC/SC driver"; 137 138 settings = lib.mkOption { 139 default = defaultSettings; 140 description = '' 141 Configuration to be written to the libncf-nci configuration files. 142 To understand the configuration format, refer to https://github.com/NXPNFCLinux/linux_libnfc-nci/tree/master/conf. 143 ''; 144 type = lib.types.attrs; 145 }; 146 147 enableIFD = lib.mkOption { 148 type = lib.types.bool; 149 default = true; 150 description = '' 151 Register ifdnfc-nci as a serial reader with pcscd. 152 ''; 153 }; 154 }; 155 156 config = lib.mkIf cfg.enable { 157 environment.systemPackages = 158 [ 159 pkgs.libnfc-nci 160 ] 161 ++ lib.optionals cfg.enableIFD [ 162 pkgs.ifdnfc-nci 163 ]; 164 165 environment.etc = { 166 "libnfc-nci.conf".text = generateSettings "nci"; 167 "libnfc-nxp-init.conf".text = generateSettings "init"; 168 "libnfc-nxp-pn547.conf".text = generateSettings "pn54x"; 169 "libnfc-nxp-pn548.conf".text = generateSettings "pn54x"; 170 }; 171 172 services.udev.packages = [ 173 config.boot.kernelPackages.nxp-pn5xx 174 ]; 175 176 boot.blacklistedKernelModules = [ 177 "nxp_nci_i2c" 178 "nxp_nci" 179 ]; 180 181 boot.extraModulePackages = [ 182 config.boot.kernelPackages.nxp-pn5xx 183 ]; 184 185 boot.kernelModules = [ 186 "nxp-pn5xx" 187 ]; 188 189 services.pcscd.readerConfigs = lib.mkIf cfg.enableIFD [ 190 '' 191 FRIENDLYNAME "NFC NCI" 192 LIBPATH ${pkgs.ifdnfc-nci}/lib/libifdnfc-nci.so 193 CHANNELID 0 194 '' 195 ]; 196 197 # NFC chip looses power when system goes to sleep / hibernate, 198 # and needs to be re-initialized upon wakeup 199 powerManagement.resumeCommands = lib.mkIf cfg.enableIFD '' 200 systemctl restart pcscd.service 201 ''; 202 }; 203 204 meta.maintainers = with lib.maintainers; [ stargate01 ]; 205}