18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Driver for NXP PN533 NFC Chip
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2011 Instituto Nokia de Tecnologia
68c2ecf20Sopenharmony_ci * Copyright (C) 2012-2013 Tieto Poland
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#define PN533_DEVICE_STD		0x1
108c2ecf20Sopenharmony_ci#define PN533_DEVICE_PASORI		0x2
118c2ecf20Sopenharmony_ci#define PN533_DEVICE_ACR122U		0x3
128c2ecf20Sopenharmony_ci#define PN533_DEVICE_PN532		0x4
138c2ecf20Sopenharmony_ci#define PN533_DEVICE_PN532_AUTOPOLL	0x5
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\
168c2ecf20Sopenharmony_ci			     NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\
178c2ecf20Sopenharmony_ci			     NFC_PROTO_NFC_DEP_MASK |\
188c2ecf20Sopenharmony_ci			     NFC_PROTO_ISO14443_B_MASK)
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#define PN533_NO_TYPE_B_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
218c2ecf20Sopenharmony_ci				   NFC_PROTO_MIFARE_MASK | \
228c2ecf20Sopenharmony_ci				   NFC_PROTO_FELICA_MASK | \
238c2ecf20Sopenharmony_ci				   NFC_PROTO_ISO14443_MASK | \
248c2ecf20Sopenharmony_ci				   NFC_PROTO_NFC_DEP_MASK)
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* Standard pn533 frame definitions (standard and extended)*/
278c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_HEADER_LEN (sizeof(struct pn533_std_frame) \
288c2ecf20Sopenharmony_ci					+ 2) /* data[0] TFI, data[1] CC */
298c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define PN533_EXT_FRAME_HEADER_LEN (sizeof(struct pn533_ext_frame) \
328c2ecf20Sopenharmony_ci					+ 2) /* data[0] TFI, data[1] CC */
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define PN533_CMD_DATAEXCH_HEAD_LEN 1
358c2ecf20Sopenharmony_ci#define PN533_CMD_DATAEXCH_DATA_MAXLEN	262
368c2ecf20Sopenharmony_ci#define PN533_CMD_DATAFRAME_MAXLEN	240	/* max data length (send) */
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci/*
398c2ecf20Sopenharmony_ci * Max extended frame payload len, excluding TFI and CC
408c2ecf20Sopenharmony_ci * which are already in PN533_FRAME_HEADER_LEN.
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_MAX_PAYLOAD_LEN 263
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci/* Preamble (1), SoPC (2), ACK Code (2), Postamble (1) */
468c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_ACK_SIZE 6
478c2ecf20Sopenharmony_ci/*
488c2ecf20Sopenharmony_ci * Preamble (1), SoPC (2), Packet Length (1), Packet Length Checksum (1),
498c2ecf20Sopenharmony_ci * Specific Application Level Error Code (1) , Postamble (1)
508c2ecf20Sopenharmony_ci */
518c2ecf20Sopenharmony_ci#define PN533_STD_ERROR_FRAME_SIZE 8
528c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_CHECKSUM(f) (f->data[f->datalen])
538c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1])
548c2ecf20Sopenharmony_ci/* Half start code (3), LEN (4) should be 0xffff for extended frame */
558c2ecf20Sopenharmony_ci#define PN533_STD_IS_EXTENDED(hdr) ((hdr)->datalen == 0xFF \
568c2ecf20Sopenharmony_ci					&& (hdr)->datalen_checksum == 0xFF)
578c2ecf20Sopenharmony_ci#define PN533_EXT_FRAME_CHECKSUM(f) (f->data[be16_to_cpu(f->datalen)])
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci/* start of frame */
608c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_SOF 0x00FF
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/* standard frame identifier: in/out/error */
638c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_IDENTIFIER(f) (f->data[0]) /* TFI */
648c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_DIR_OUT 0xD4
658c2ecf20Sopenharmony_ci#define PN533_STD_FRAME_DIR_IN 0xD5
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/* PN533 Commands */
688c2ecf20Sopenharmony_ci#define PN533_FRAME_CMD(f) (f->data[1])
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define PN533_CMD_GET_FIRMWARE_VERSION 0x02
718c2ecf20Sopenharmony_ci#define PN533_CMD_SAM_CONFIGURATION 0x14
728c2ecf20Sopenharmony_ci#define PN533_CMD_RF_CONFIGURATION 0x32
738c2ecf20Sopenharmony_ci#define PN533_CMD_IN_DATA_EXCHANGE 0x40
748c2ecf20Sopenharmony_ci#define PN533_CMD_IN_COMM_THRU     0x42
758c2ecf20Sopenharmony_ci#define PN533_CMD_IN_LIST_PASSIVE_TARGET 0x4A
768c2ecf20Sopenharmony_ci#define PN533_CMD_IN_ATR 0x50
778c2ecf20Sopenharmony_ci#define PN533_CMD_IN_RELEASE 0x52
788c2ecf20Sopenharmony_ci#define PN533_CMD_IN_JUMP_FOR_DEP 0x56
798c2ecf20Sopenharmony_ci#define PN533_CMD_IN_AUTOPOLL 0x60
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci#define PN533_CMD_TG_INIT_AS_TARGET 0x8c
828c2ecf20Sopenharmony_ci#define PN533_CMD_TG_GET_DATA 0x86
838c2ecf20Sopenharmony_ci#define PN533_CMD_TG_SET_DATA 0x8e
848c2ecf20Sopenharmony_ci#define PN533_CMD_TG_SET_META_DATA 0x94
858c2ecf20Sopenharmony_ci#define PN533_CMD_UNDEF 0xff
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#define PN533_CMD_RESPONSE(cmd) (cmd + 1)
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/* PN533 Return codes */
908c2ecf20Sopenharmony_ci#define PN533_CMD_RET_MASK 0x3F
918c2ecf20Sopenharmony_ci#define PN533_CMD_MI_MASK 0x40
928c2ecf20Sopenharmony_ci#define PN533_CMD_RET_SUCCESS 0x00
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci#define PN533_FRAME_DATALEN_ACK 0x00
958c2ecf20Sopenharmony_ci#define PN533_FRAME_DATALEN_ERROR 0x01
968c2ecf20Sopenharmony_ci#define PN533_FRAME_DATALEN_EXTENDED 0xFF
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_cienum  pn533_protocol_type {
998c2ecf20Sopenharmony_ci	PN533_PROTO_REQ_ACK_RESP = 0,
1008c2ecf20Sopenharmony_ci	PN533_PROTO_REQ_RESP
1018c2ecf20Sopenharmony_ci};
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci/* Poll modulations */
1048c2ecf20Sopenharmony_cienum {
1058c2ecf20Sopenharmony_ci	PN533_POLL_MOD_106KBPS_A,
1068c2ecf20Sopenharmony_ci	PN533_POLL_MOD_212KBPS_FELICA,
1078c2ecf20Sopenharmony_ci	PN533_POLL_MOD_424KBPS_FELICA,
1088c2ecf20Sopenharmony_ci	PN533_POLL_MOD_106KBPS_JEWEL,
1098c2ecf20Sopenharmony_ci	PN533_POLL_MOD_847KBPS_B,
1108c2ecf20Sopenharmony_ci	PN533_LISTEN_MOD,
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	__PN533_POLL_MOD_AFTER_LAST,
1138c2ecf20Sopenharmony_ci};
1148c2ecf20Sopenharmony_ci#define PN533_POLL_MOD_MAX (__PN533_POLL_MOD_AFTER_LAST - 1)
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistruct pn533_std_frame {
1178c2ecf20Sopenharmony_ci	u8 preamble;
1188c2ecf20Sopenharmony_ci	__be16 start_frame;
1198c2ecf20Sopenharmony_ci	u8 datalen;
1208c2ecf20Sopenharmony_ci	u8 datalen_checksum;
1218c2ecf20Sopenharmony_ci	u8 data[];
1228c2ecf20Sopenharmony_ci} __packed;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistruct pn533_ext_frame {	/* Extended Information frame */
1258c2ecf20Sopenharmony_ci	u8 preamble;
1268c2ecf20Sopenharmony_ci	__be16 start_frame;
1278c2ecf20Sopenharmony_ci	__be16 eif_flag;	/* fixed to 0xFFFF */
1288c2ecf20Sopenharmony_ci	__be16 datalen;
1298c2ecf20Sopenharmony_ci	u8 datalen_checksum;
1308c2ecf20Sopenharmony_ci	u8 data[];
1318c2ecf20Sopenharmony_ci} __packed;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistruct pn533 {
1348c2ecf20Sopenharmony_ci	struct nfc_dev *nfc_dev;
1358c2ecf20Sopenharmony_ci	u32 device_type;
1368c2ecf20Sopenharmony_ci	enum pn533_protocol_type protocol_type;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	struct sk_buff_head resp_q;
1398c2ecf20Sopenharmony_ci	struct sk_buff_head fragment_skb;
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	struct workqueue_struct	*wq;
1428c2ecf20Sopenharmony_ci	struct work_struct cmd_work;
1438c2ecf20Sopenharmony_ci	struct work_struct cmd_complete_work;
1448c2ecf20Sopenharmony_ci	struct delayed_work poll_work;
1458c2ecf20Sopenharmony_ci	struct work_struct mi_rx_work;
1468c2ecf20Sopenharmony_ci	struct work_struct mi_tx_work;
1478c2ecf20Sopenharmony_ci	struct work_struct mi_tm_rx_work;
1488c2ecf20Sopenharmony_ci	struct work_struct mi_tm_tx_work;
1498c2ecf20Sopenharmony_ci	struct work_struct tg_work;
1508c2ecf20Sopenharmony_ci	struct work_struct rf_work;
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	struct list_head cmd_queue;
1538c2ecf20Sopenharmony_ci	struct pn533_cmd *cmd;
1548c2ecf20Sopenharmony_ci	u8 cmd_pending;
1558c2ecf20Sopenharmony_ci	struct mutex cmd_lock;  /* protects cmd queue */
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	void *cmd_complete_mi_arg;
1588c2ecf20Sopenharmony_ci	void *cmd_complete_dep_arg;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1];
1618c2ecf20Sopenharmony_ci	u8 poll_mod_count;
1628c2ecf20Sopenharmony_ci	u8 poll_mod_curr;
1638c2ecf20Sopenharmony_ci	u8 poll_dep;
1648c2ecf20Sopenharmony_ci	u32 poll_protocols;
1658c2ecf20Sopenharmony_ci	u32 listen_protocols;
1668c2ecf20Sopenharmony_ci	struct timer_list listen_timer;
1678c2ecf20Sopenharmony_ci	int cancel_listen;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	u8 *gb;
1708c2ecf20Sopenharmony_ci	size_t gb_len;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	u8 tgt_available_prots;
1738c2ecf20Sopenharmony_ci	u8 tgt_active_prot;
1748c2ecf20Sopenharmony_ci	u8 tgt_mode;
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	struct pn533_frame_ops *ops;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	struct device *dev;
1798c2ecf20Sopenharmony_ci	void *phy;
1808c2ecf20Sopenharmony_ci	struct pn533_phy_ops *phy_ops;
1818c2ecf20Sopenharmony_ci};
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_citypedef int (*pn533_send_async_complete_t) (struct pn533 *dev, void *arg,
1848c2ecf20Sopenharmony_ci					struct sk_buff *resp);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_cistruct pn533_cmd {
1878c2ecf20Sopenharmony_ci	struct list_head queue;
1888c2ecf20Sopenharmony_ci	u8 code;
1898c2ecf20Sopenharmony_ci	int status;
1908c2ecf20Sopenharmony_ci	struct sk_buff *req;
1918c2ecf20Sopenharmony_ci	struct sk_buff *resp;
1928c2ecf20Sopenharmony_ci	pn533_send_async_complete_t  complete_cb;
1938c2ecf20Sopenharmony_ci	void *complete_cb_context;
1948c2ecf20Sopenharmony_ci};
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_cistruct pn533_frame_ops {
1988c2ecf20Sopenharmony_ci	void (*tx_frame_init)(void *frame, u8 cmd_code);
1998c2ecf20Sopenharmony_ci	void (*tx_frame_finish)(void *frame);
2008c2ecf20Sopenharmony_ci	void (*tx_update_payload_len)(void *frame, int len);
2018c2ecf20Sopenharmony_ci	int tx_header_len;
2028c2ecf20Sopenharmony_ci	int tx_tail_len;
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	bool (*rx_is_frame_valid)(void *frame, struct pn533 *dev);
2058c2ecf20Sopenharmony_ci	bool (*rx_frame_is_ack)(void *frame);
2068c2ecf20Sopenharmony_ci	int (*rx_frame_size)(void *frame);
2078c2ecf20Sopenharmony_ci	int rx_header_len;
2088c2ecf20Sopenharmony_ci	int rx_tail_len;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	int max_payload_len;
2118c2ecf20Sopenharmony_ci	u8 (*get_cmd_code)(void *frame);
2128c2ecf20Sopenharmony_ci};
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cistruct pn533_phy_ops {
2168c2ecf20Sopenharmony_ci	int (*send_frame)(struct pn533 *priv,
2178c2ecf20Sopenharmony_ci			  struct sk_buff *out);
2188c2ecf20Sopenharmony_ci	int (*send_ack)(struct pn533 *dev, gfp_t flags);
2198c2ecf20Sopenharmony_ci	void (*abort_cmd)(struct pn533 *priv, gfp_t flags);
2208c2ecf20Sopenharmony_ci	/*
2218c2ecf20Sopenharmony_ci	 * dev_up and dev_down are optional.
2228c2ecf20Sopenharmony_ci	 * They are used to inform the phy layer that the nfc chip
2238c2ecf20Sopenharmony_ci	 * is going to be really used very soon. The phy layer can then
2248c2ecf20Sopenharmony_ci	 * bring up it's interface to the chip and have it suspended for power
2258c2ecf20Sopenharmony_ci	 * saving reasons otherwise.
2268c2ecf20Sopenharmony_ci	 */
2278c2ecf20Sopenharmony_ci	int (*dev_up)(struct pn533 *priv);
2288c2ecf20Sopenharmony_ci	int (*dev_down)(struct pn533 *priv);
2298c2ecf20Sopenharmony_ci};
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_cistruct pn533 *pn53x_common_init(u32 device_type,
2338c2ecf20Sopenharmony_ci				enum pn533_protocol_type protocol_type,
2348c2ecf20Sopenharmony_ci				void *phy,
2358c2ecf20Sopenharmony_ci				struct pn533_phy_ops *phy_ops,
2368c2ecf20Sopenharmony_ci				struct pn533_frame_ops *fops,
2378c2ecf20Sopenharmony_ci				struct device *dev);
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ciint pn533_finalize_setup(struct pn533 *dev);
2408c2ecf20Sopenharmony_civoid pn53x_common_clean(struct pn533 *priv);
2418c2ecf20Sopenharmony_civoid pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status);
2428c2ecf20Sopenharmony_ciint pn532_i2c_nfc_alloc(struct pn533 *priv, u32 protocols,
2438c2ecf20Sopenharmony_ci			struct device *parent);
2448c2ecf20Sopenharmony_ciint pn53x_register_nfc(struct pn533 *priv, u32 protocols,
2458c2ecf20Sopenharmony_ci			struct device *parent);
2468c2ecf20Sopenharmony_civoid pn53x_unregister_nfc(struct pn533 *priv);
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cibool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame);
2498c2ecf20Sopenharmony_cibool pn533_rx_frame_is_ack(void *_frame);
250