18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * NFC Digital Protocol stack 48c2ecf20Sopenharmony_ci * Copyright (c) 2013, Intel Corporation. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __NFC_DIGITAL_H 88c2ecf20Sopenharmony_ci#define __NFC_DIGITAL_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 118c2ecf20Sopenharmony_ci#include <net/nfc/nfc.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/** 148c2ecf20Sopenharmony_ci * Configuration types for in_configure_hw and tg_configure_hw. 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_cienum { 178c2ecf20Sopenharmony_ci NFC_DIGITAL_CONFIG_RF_TECH = 0, 188c2ecf20Sopenharmony_ci NFC_DIGITAL_CONFIG_FRAMING, 198c2ecf20Sopenharmony_ci}; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/** 228c2ecf20Sopenharmony_ci * RF technology values passed as param argument to in_configure_hw and 238c2ecf20Sopenharmony_ci * tg_configure_hw for NFC_DIGITAL_CONFIG_RF_TECH configuration type. 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_cienum { 268c2ecf20Sopenharmony_ci NFC_DIGITAL_RF_TECH_106A = 0, 278c2ecf20Sopenharmony_ci NFC_DIGITAL_RF_TECH_212F, 288c2ecf20Sopenharmony_ci NFC_DIGITAL_RF_TECH_424F, 298c2ecf20Sopenharmony_ci NFC_DIGITAL_RF_TECH_ISO15693, 308c2ecf20Sopenharmony_ci NFC_DIGITAL_RF_TECH_106B, 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci NFC_DIGITAL_RF_TECH_LAST, 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/** 368c2ecf20Sopenharmony_ci * Framing configuration passed as param argument to in_configure_hw and 378c2ecf20Sopenharmony_ci * tg_configure_hw for NFC_DIGITAL_CONFIG_FRAMING configuration type. 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_cienum { 408c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_SHORT = 0, 418c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_STANDARD, 428c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A, 438c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_ANTICOL_COMPLETE, 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_T1T, 468c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_T2T, 478c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_T4T, 488c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCA_NFC_DEP, 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCF, 518c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCF_T3T, 528c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCF_NFC_DEP, 538c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED, 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_ISO15693_INVENTORY, 568c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_ISO15693_T5T, 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCB, 598c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_NFCB_T4T, 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci NFC_DIGITAL_FRAMING_LAST, 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define DIGITAL_MDAA_NFCID1_SIZE 3 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistruct digital_tg_mdaa_params { 678c2ecf20Sopenharmony_ci u16 sens_res; 688c2ecf20Sopenharmony_ci u8 nfcid1[DIGITAL_MDAA_NFCID1_SIZE]; 698c2ecf20Sopenharmony_ci u8 sel_res; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci u8 nfcid2[NFC_NFCID2_MAXSIZE]; 728c2ecf20Sopenharmony_ci u16 sc; 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistruct nfc_digital_dev; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci/** 788c2ecf20Sopenharmony_ci * nfc_digital_cmd_complete_t - Definition of command result callback 798c2ecf20Sopenharmony_ci * 808c2ecf20Sopenharmony_ci * @ddev: nfc_digital_device ref 818c2ecf20Sopenharmony_ci * @arg: user data 828c2ecf20Sopenharmony_ci * @resp: response data 838c2ecf20Sopenharmony_ci * 848c2ecf20Sopenharmony_ci * resp pointer can be an error code and will be checked with IS_ERR() macro. 858c2ecf20Sopenharmony_ci * The callback is responsible for freeing resp sk_buff. 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_citypedef void (*nfc_digital_cmd_complete_t)(struct nfc_digital_dev *ddev, 888c2ecf20Sopenharmony_ci void *arg, struct sk_buff *resp); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/** 918c2ecf20Sopenharmony_ci * Device side NFC Digital operations 928c2ecf20Sopenharmony_ci * 938c2ecf20Sopenharmony_ci * Initiator mode: 948c2ecf20Sopenharmony_ci * @in_configure_hw: Hardware configuration for RF technology and communication 958c2ecf20Sopenharmony_ci * framing in initiator mode. This is a synchronous function. 968c2ecf20Sopenharmony_ci * @in_send_cmd: Initiator mode data exchange using RF technology and framing 978c2ecf20Sopenharmony_ci * previously set with in_configure_hw. The peer response is returned 988c2ecf20Sopenharmony_ci * through callback cb. If an io error occurs or the peer didn't reply 998c2ecf20Sopenharmony_ci * within the specified timeout (ms), the error code is passed back through 1008c2ecf20Sopenharmony_ci * the resp pointer. This is an asynchronous function. 1018c2ecf20Sopenharmony_ci * 1028c2ecf20Sopenharmony_ci * Target mode: Only NFC-DEP protocol is supported in target mode. 1038c2ecf20Sopenharmony_ci * @tg_configure_hw: Hardware configuration for RF technology and communication 1048c2ecf20Sopenharmony_ci * framing in target mode. This is a synchronous function. 1058c2ecf20Sopenharmony_ci * @tg_send_cmd: Target mode data exchange using RF technology and framing 1068c2ecf20Sopenharmony_ci * previously set with tg_configure_hw. The peer next command is returned 1078c2ecf20Sopenharmony_ci * through callback cb. If an io error occurs or the peer didn't reply 1088c2ecf20Sopenharmony_ci * within the specified timeout (ms), the error code is passed back through 1098c2ecf20Sopenharmony_ci * the resp pointer. This is an asynchronous function. 1108c2ecf20Sopenharmony_ci * @tg_listen: Put the device in listen mode waiting for data from the peer 1118c2ecf20Sopenharmony_ci * device. This is an asynchronous function. 1128c2ecf20Sopenharmony_ci * @tg_listen_mdaa: If supported, put the device in automatic listen mode with 1138c2ecf20Sopenharmony_ci * mode detection and automatic anti-collision. In this mode, the device 1148c2ecf20Sopenharmony_ci * automatically detects the RF technology and executes the anti-collision 1158c2ecf20Sopenharmony_ci * detection using the command responses specified in mdaa_params. The 1168c2ecf20Sopenharmony_ci * mdaa_params structure contains SENS_RES, NFCID1, and SEL_RES for 106A RF 1178c2ecf20Sopenharmony_ci * tech. NFCID2 and system code (sc) for 212F and 424F. The driver returns 1188c2ecf20Sopenharmony_ci * the NFC-DEP ATR_REQ command through cb. The digital stack deducts the RF 1198c2ecf20Sopenharmony_ci * tech by analyzing the SoD of the frame containing the ATR_REQ command. 1208c2ecf20Sopenharmony_ci * This is an asynchronous function. 1218c2ecf20Sopenharmony_ci * @tg_listen_md: If supported, put the device in automatic listen mode with 1228c2ecf20Sopenharmony_ci * mode detection but without automatic anti-collision. In this mode, the 1238c2ecf20Sopenharmony_ci * device automatically detects the RF technology. What the actual 1248c2ecf20Sopenharmony_ci * RF technology is can be retrieved by calling @tg_get_rf_tech. 1258c2ecf20Sopenharmony_ci * The digital stack will then perform the appropriate anti-collision 1268c2ecf20Sopenharmony_ci * sequence. This is an asynchronous function. 1278c2ecf20Sopenharmony_ci * @tg_get_rf_tech: Required when @tg_listen_md is supported, unused otherwise. 1288c2ecf20Sopenharmony_ci * Return the RF Technology that was detected by the @tg_listen_md call. 1298c2ecf20Sopenharmony_ci * This is a synchronous function. 1308c2ecf20Sopenharmony_ci * 1318c2ecf20Sopenharmony_ci * @switch_rf: Turns device radio on or off. The stack does not call explicitly 1328c2ecf20Sopenharmony_ci * switch_rf to turn the radio on. A call to in|tg_configure_hw must turn 1338c2ecf20Sopenharmony_ci * the device radio on. 1348c2ecf20Sopenharmony_ci * @abort_cmd: Discard the last sent command. 1358c2ecf20Sopenharmony_ci * 1368c2ecf20Sopenharmony_ci * Notes: Asynchronous functions have a timeout parameter. It is the driver 1378c2ecf20Sopenharmony_ci * responsibility to call the digital stack back through the 1388c2ecf20Sopenharmony_ci * nfc_digital_cmd_complete_t callback when no RF respsonse has been 1398c2ecf20Sopenharmony_ci * received within the specified time (in milliseconds). In that case the 1408c2ecf20Sopenharmony_ci * driver must set the resp sk_buff to ERR_PTR(-ETIMEDOUT). 1418c2ecf20Sopenharmony_ci * Since the digital stack serializes commands to be sent, it's mandatory 1428c2ecf20Sopenharmony_ci * for the driver to handle the timeout correctly. Otherwise the stack 1438c2ecf20Sopenharmony_ci * would not be able to send new commands, waiting for the reply of the 1448c2ecf20Sopenharmony_ci * current one. 1458c2ecf20Sopenharmony_ci */ 1468c2ecf20Sopenharmony_cistruct nfc_digital_ops { 1478c2ecf20Sopenharmony_ci int (*in_configure_hw)(struct nfc_digital_dev *ddev, int type, 1488c2ecf20Sopenharmony_ci int param); 1498c2ecf20Sopenharmony_ci int (*in_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb, 1508c2ecf20Sopenharmony_ci u16 timeout, nfc_digital_cmd_complete_t cb, 1518c2ecf20Sopenharmony_ci void *arg); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci int (*tg_configure_hw)(struct nfc_digital_dev *ddev, int type, 1548c2ecf20Sopenharmony_ci int param); 1558c2ecf20Sopenharmony_ci int (*tg_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb, 1568c2ecf20Sopenharmony_ci u16 timeout, nfc_digital_cmd_complete_t cb, 1578c2ecf20Sopenharmony_ci void *arg); 1588c2ecf20Sopenharmony_ci int (*tg_listen)(struct nfc_digital_dev *ddev, u16 timeout, 1598c2ecf20Sopenharmony_ci nfc_digital_cmd_complete_t cb, void *arg); 1608c2ecf20Sopenharmony_ci int (*tg_listen_mdaa)(struct nfc_digital_dev *ddev, 1618c2ecf20Sopenharmony_ci struct digital_tg_mdaa_params *mdaa_params, 1628c2ecf20Sopenharmony_ci u16 timeout, nfc_digital_cmd_complete_t cb, 1638c2ecf20Sopenharmony_ci void *arg); 1648c2ecf20Sopenharmony_ci int (*tg_listen_md)(struct nfc_digital_dev *ddev, u16 timeout, 1658c2ecf20Sopenharmony_ci nfc_digital_cmd_complete_t cb, void *arg); 1668c2ecf20Sopenharmony_ci int (*tg_get_rf_tech)(struct nfc_digital_dev *ddev, u8 *rf_tech); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci int (*switch_rf)(struct nfc_digital_dev *ddev, bool on); 1698c2ecf20Sopenharmony_ci void (*abort_cmd)(struct nfc_digital_dev *ddev); 1708c2ecf20Sopenharmony_ci}; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci#define NFC_DIGITAL_POLL_MODE_COUNT_MAX 6 /* 106A, 212F, and 424F in & tg */ 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_citypedef int (*digital_poll_t)(struct nfc_digital_dev *ddev, u8 rf_tech); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistruct digital_poll_tech { 1778c2ecf20Sopenharmony_ci u8 rf_tech; 1788c2ecf20Sopenharmony_ci digital_poll_t poll_func; 1798c2ecf20Sopenharmony_ci}; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci/** 1828c2ecf20Sopenharmony_ci * Driver capabilities - bit mask made of the following values 1838c2ecf20Sopenharmony_ci * 1848c2ecf20Sopenharmony_ci * @NFC_DIGITAL_DRV_CAPS_IN_CRC: The driver handles CRC calculation in initiator 1858c2ecf20Sopenharmony_ci * mode. 1868c2ecf20Sopenharmony_ci * @NFC_DIGITAL_DRV_CAPS_TG_CRC: The driver handles CRC calculation in target 1878c2ecf20Sopenharmony_ci * mode. 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_ci#define NFC_DIGITAL_DRV_CAPS_IN_CRC 0x0001 1908c2ecf20Sopenharmony_ci#define NFC_DIGITAL_DRV_CAPS_TG_CRC 0x0002 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistruct nfc_digital_dev { 1938c2ecf20Sopenharmony_ci struct nfc_dev *nfc_dev; 1948c2ecf20Sopenharmony_ci struct nfc_digital_ops *ops; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci u32 protocols; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci int tx_headroom; 1998c2ecf20Sopenharmony_ci int tx_tailroom; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci u32 driver_capabilities; 2028c2ecf20Sopenharmony_ci void *driver_data; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci struct digital_poll_tech poll_techs[NFC_DIGITAL_POLL_MODE_COUNT_MAX]; 2058c2ecf20Sopenharmony_ci u8 poll_tech_count; 2068c2ecf20Sopenharmony_ci u8 poll_tech_index; 2078c2ecf20Sopenharmony_ci struct mutex poll_lock; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci struct work_struct cmd_work; 2108c2ecf20Sopenharmony_ci struct work_struct cmd_complete_work; 2118c2ecf20Sopenharmony_ci struct list_head cmd_queue; 2128c2ecf20Sopenharmony_ci struct mutex cmd_lock; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci struct delayed_work poll_work; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci u8 curr_protocol; 2178c2ecf20Sopenharmony_ci u8 curr_rf_tech; 2188c2ecf20Sopenharmony_ci u8 curr_nfc_dep_pni; 2198c2ecf20Sopenharmony_ci u8 did; 2208c2ecf20Sopenharmony_ci u16 dep_rwt; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci u8 local_payload_max; 2238c2ecf20Sopenharmony_ci u8 remote_payload_max; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci struct sk_buff *chaining_skb; 2268c2ecf20Sopenharmony_ci struct digital_data_exch *data_exch; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci int atn_count; 2298c2ecf20Sopenharmony_ci int nack_count; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci struct sk_buff *saved_skb; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci u16 target_fsc; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci int (*skb_check_crc)(struct sk_buff *skb); 2368c2ecf20Sopenharmony_ci void (*skb_add_crc)(struct sk_buff *skb); 2378c2ecf20Sopenharmony_ci}; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cistruct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops, 2408c2ecf20Sopenharmony_ci __u32 supported_protocols, 2418c2ecf20Sopenharmony_ci __u32 driver_capabilities, 2428c2ecf20Sopenharmony_ci int tx_headroom, 2438c2ecf20Sopenharmony_ci int tx_tailroom); 2448c2ecf20Sopenharmony_civoid nfc_digital_free_device(struct nfc_digital_dev *ndev); 2458c2ecf20Sopenharmony_ciint nfc_digital_register_device(struct nfc_digital_dev *ndev); 2468c2ecf20Sopenharmony_civoid nfc_digital_unregister_device(struct nfc_digital_dev *ndev); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_cistatic inline void nfc_digital_set_parent_dev(struct nfc_digital_dev *ndev, 2498c2ecf20Sopenharmony_ci struct device *dev) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci nfc_set_parent_dev(ndev->nfc_dev, dev); 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic inline void nfc_digital_set_drvdata(struct nfc_digital_dev *dev, 2558c2ecf20Sopenharmony_ci void *data) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci dev->driver_data = data; 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_cistatic inline void *nfc_digital_get_drvdata(struct nfc_digital_dev *dev) 2618c2ecf20Sopenharmony_ci{ 2628c2ecf20Sopenharmony_ci return dev->driver_data; 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci#endif /* __NFC_DIGITAL_H */ 266