1c656aa4cSLars Poeschel // SPDX-License-Identifier: GPL-2.0+ 2c656aa4cSLars Poeschel /* 3c656aa4cSLars Poeschel * Driver for NXP PN532 NFC Chip - UART transport layer 4c656aa4cSLars Poeschel * 5c656aa4cSLars Poeschel * Copyright (C) 2018 Lemonage Software GmbH 6c656aa4cSLars Poeschel * Author: Lars Pöschel <poeschel@lemonage.de> 7c656aa4cSLars Poeschel * All rights reserved. 8c656aa4cSLars Poeschel */ 9c656aa4cSLars Poeschel 10c656aa4cSLars Poeschel #include <linux/device.h> 11c656aa4cSLars Poeschel #include <linux/kernel.h> 12c656aa4cSLars Poeschel #include <linux/module.h> 13c656aa4cSLars Poeschel #include <linux/nfc.h> 14c656aa4cSLars Poeschel #include <linux/netdevice.h> 15c656aa4cSLars Poeschel #include <linux/of.h> 16c656aa4cSLars Poeschel #include <linux/serdev.h> 17c656aa4cSLars Poeschel #include "pn533.h" 18c656aa4cSLars Poeschel 19c656aa4cSLars Poeschel #define PN532_UART_SKB_BUFF_LEN (PN533_CMD_DATAEXCH_DATA_MAXLEN * 2) 20c656aa4cSLars Poeschel 21c656aa4cSLars Poeschel enum send_wakeup { 22c656aa4cSLars Poeschel PN532_SEND_NO_WAKEUP = 0, 23c656aa4cSLars Poeschel PN532_SEND_WAKEUP, 24c656aa4cSLars Poeschel PN532_SEND_LAST_WAKEUP, 25c656aa4cSLars Poeschel }; 26c656aa4cSLars Poeschel 27c656aa4cSLars Poeschel 28c656aa4cSLars Poeschel struct pn532_uart_phy { 29c656aa4cSLars Poeschel struct serdev_device *serdev; 30c656aa4cSLars Poeschel struct sk_buff *recv_skb; 31c656aa4cSLars Poeschel struct pn533 *priv; 32c656aa4cSLars Poeschel /* 33c656aa4cSLars Poeschel * send_wakeup variable is used to control if we need to send a wakeup 34c656aa4cSLars Poeschel * request to the pn532 chip prior to our actual command. There is a 35c656aa4cSLars Poeschel * little propability of a race condition. We decided to not mutex the 36c656aa4cSLars Poeschel * variable as the worst that could happen is, that we send a wakeup 37c656aa4cSLars Poeschel * to the chip that is already awake. This does not hurt. It is a 38c656aa4cSLars Poeschel * no-op to the chip. 39c656aa4cSLars Poeschel */ 40c656aa4cSLars Poeschel enum send_wakeup send_wakeup; 41c656aa4cSLars Poeschel struct timer_list cmd_timeout; 42c656aa4cSLars Poeschel struct sk_buff *cur_out_buf; 43c656aa4cSLars Poeschel }; 44c656aa4cSLars Poeschel 45c656aa4cSLars Poeschel static int pn532_uart_send_frame(struct pn533 *dev, 46c656aa4cSLars Poeschel struct sk_buff *out) 47c656aa4cSLars Poeschel { 48c656aa4cSLars Poeschel /* wakeup sequence and dummy bytes for waiting time */ 49c656aa4cSLars Poeschel static const u8 wakeup[] = { 50c656aa4cSLars Poeschel 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51c656aa4cSLars Poeschel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 52c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = dev->phy; 53c656aa4cSLars Poeschel int err; 54c656aa4cSLars Poeschel 55c656aa4cSLars Poeschel print_hex_dump_debug("PN532_uart TX: ", DUMP_PREFIX_NONE, 16, 1, 56c656aa4cSLars Poeschel out->data, out->len, false); 57c656aa4cSLars Poeschel 58c656aa4cSLars Poeschel pn532->cur_out_buf = out; 59c656aa4cSLars Poeschel if (pn532->send_wakeup) { 60c656aa4cSLars Poeschel err = serdev_device_write(pn532->serdev, 61c656aa4cSLars Poeschel wakeup, sizeof(wakeup), 62c656aa4cSLars Poeschel MAX_SCHEDULE_TIMEOUT); 63c656aa4cSLars Poeschel if (err < 0) 64c656aa4cSLars Poeschel return err; 65c656aa4cSLars Poeschel } 66c656aa4cSLars Poeschel 67c656aa4cSLars Poeschel if (pn532->send_wakeup == PN532_SEND_LAST_WAKEUP) 68c656aa4cSLars Poeschel pn532->send_wakeup = PN532_SEND_NO_WAKEUP; 69c656aa4cSLars Poeschel 70c656aa4cSLars Poeschel err = serdev_device_write(pn532->serdev, out->data, out->len, 71c656aa4cSLars Poeschel MAX_SCHEDULE_TIMEOUT); 72c656aa4cSLars Poeschel if (err < 0) 73c656aa4cSLars Poeschel return err; 74c656aa4cSLars Poeschel 75c656aa4cSLars Poeschel mod_timer(&pn532->cmd_timeout, HZ / 40 + jiffies); 76c656aa4cSLars Poeschel return 0; 77c656aa4cSLars Poeschel } 78c656aa4cSLars Poeschel 79c656aa4cSLars Poeschel static int pn532_uart_send_ack(struct pn533 *dev, gfp_t flags) 80c656aa4cSLars Poeschel { 81c656aa4cSLars Poeschel /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ 82c656aa4cSLars Poeschel static const u8 ack[PN533_STD_FRAME_ACK_SIZE] = { 83c656aa4cSLars Poeschel 0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; 84c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = dev->phy; 85c656aa4cSLars Poeschel int err; 86c656aa4cSLars Poeschel 87c656aa4cSLars Poeschel err = serdev_device_write(pn532->serdev, ack, sizeof(ack), 88c656aa4cSLars Poeschel MAX_SCHEDULE_TIMEOUT); 89c656aa4cSLars Poeschel if (err < 0) 90c656aa4cSLars Poeschel return err; 91c656aa4cSLars Poeschel 92c656aa4cSLars Poeschel return 0; 93c656aa4cSLars Poeschel } 94c656aa4cSLars Poeschel 95c656aa4cSLars Poeschel static void pn532_uart_abort_cmd(struct pn533 *dev, gfp_t flags) 96c656aa4cSLars Poeschel { 97c656aa4cSLars Poeschel /* An ack will cancel the last issued command */ 98c656aa4cSLars Poeschel pn532_uart_send_ack(dev, flags); 99c656aa4cSLars Poeschel /* schedule cmd_complete_work to finish current command execution */ 100c656aa4cSLars Poeschel pn533_recv_frame(dev, NULL, -ENOENT); 101c656aa4cSLars Poeschel } 102c656aa4cSLars Poeschel 1031e37be7dSLars Poeschel static int pn532_dev_up(struct pn533 *dev) 104c656aa4cSLars Poeschel { 105c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = dev->phy; 1061e37be7dSLars Poeschel int ret = 0; 107c656aa4cSLars Poeschel 1081e37be7dSLars Poeschel ret = serdev_device_open(pn532->serdev); 1091e37be7dSLars Poeschel if (ret) 1101e37be7dSLars Poeschel return ret; 1111e37be7dSLars Poeschel 112c656aa4cSLars Poeschel pn532->send_wakeup = PN532_SEND_LAST_WAKEUP; 1131e37be7dSLars Poeschel return ret; 114c656aa4cSLars Poeschel } 115c656aa4cSLars Poeschel 1161e37be7dSLars Poeschel static int pn532_dev_down(struct pn533 *dev) 117c656aa4cSLars Poeschel { 118c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = dev->phy; 119c656aa4cSLars Poeschel 120c656aa4cSLars Poeschel serdev_device_close(pn532->serdev); 121c656aa4cSLars Poeschel pn532->send_wakeup = PN532_SEND_WAKEUP; 1221e37be7dSLars Poeschel 1231e37be7dSLars Poeschel return 0; 124c656aa4cSLars Poeschel } 125c656aa4cSLars Poeschel 126bc642817SRikard Falkeborn static const struct pn533_phy_ops uart_phy_ops = { 127c656aa4cSLars Poeschel .send_frame = pn532_uart_send_frame, 128c656aa4cSLars Poeschel .send_ack = pn532_uart_send_ack, 129c656aa4cSLars Poeschel .abort_cmd = pn532_uart_abort_cmd, 130c656aa4cSLars Poeschel .dev_up = pn532_dev_up, 131c656aa4cSLars Poeschel .dev_down = pn532_dev_down, 132c656aa4cSLars Poeschel }; 133c656aa4cSLars Poeschel 134c656aa4cSLars Poeschel static void pn532_cmd_timeout(struct timer_list *t) 135c656aa4cSLars Poeschel { 136c656aa4cSLars Poeschel struct pn532_uart_phy *dev = from_timer(dev, t, cmd_timeout); 137c656aa4cSLars Poeschel 138c656aa4cSLars Poeschel pn532_uart_send_frame(dev->priv, dev->cur_out_buf); 139c656aa4cSLars Poeschel } 140c656aa4cSLars Poeschel 141c656aa4cSLars Poeschel /* 142c656aa4cSLars Poeschel * scans the buffer if it contains a pn532 frame. It is not checked if the 143c656aa4cSLars Poeschel * frame is really valid. This is later done with pn533_rx_frame_is_valid. 144c656aa4cSLars Poeschel * This is useful for malformed or errornous transmitted frames. Adjusts the 145c656aa4cSLars Poeschel * bufferposition where the frame starts, since pn533_recv_frame expects a 146c656aa4cSLars Poeschel * well formed frame. 147c656aa4cSLars Poeschel */ 148c656aa4cSLars Poeschel static int pn532_uart_rx_is_frame(struct sk_buff *skb) 149c656aa4cSLars Poeschel { 150c656aa4cSLars Poeschel struct pn533_std_frame *std; 151c656aa4cSLars Poeschel struct pn533_ext_frame *ext; 152c656aa4cSLars Poeschel u16 frame_len; 153c656aa4cSLars Poeschel int i; 154c656aa4cSLars Poeschel 155c656aa4cSLars Poeschel for (i = 0; i + PN533_STD_FRAME_ACK_SIZE <= skb->len; i++) { 156c656aa4cSLars Poeschel std = (struct pn533_std_frame *)&skb->data[i]; 157c656aa4cSLars Poeschel /* search start code */ 158c656aa4cSLars Poeschel if (std->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF)) 159c656aa4cSLars Poeschel continue; 160c656aa4cSLars Poeschel 161c656aa4cSLars Poeschel /* frame type */ 162c656aa4cSLars Poeschel switch (std->datalen) { 163c656aa4cSLars Poeschel case PN533_FRAME_DATALEN_ACK: 164c656aa4cSLars Poeschel if (std->datalen_checksum == 0xff) { 165c656aa4cSLars Poeschel skb_pull(skb, i); 166c656aa4cSLars Poeschel return 1; 167c656aa4cSLars Poeschel } 168c656aa4cSLars Poeschel 169c656aa4cSLars Poeschel break; 170c656aa4cSLars Poeschel case PN533_FRAME_DATALEN_ERROR: 171c656aa4cSLars Poeschel if ((std->datalen_checksum == 0xff) && 172c656aa4cSLars Poeschel (skb->len >= 173c656aa4cSLars Poeschel PN533_STD_ERROR_FRAME_SIZE)) { 174c656aa4cSLars Poeschel skb_pull(skb, i); 175c656aa4cSLars Poeschel return 1; 176c656aa4cSLars Poeschel } 177c656aa4cSLars Poeschel 178c656aa4cSLars Poeschel break; 179c656aa4cSLars Poeschel case PN533_FRAME_DATALEN_EXTENDED: 180c656aa4cSLars Poeschel ext = (struct pn533_ext_frame *)&skb->data[i]; 181c656aa4cSLars Poeschel frame_len = be16_to_cpu(ext->datalen); 182c656aa4cSLars Poeschel if (skb->len >= frame_len + 183c656aa4cSLars Poeschel sizeof(struct pn533_ext_frame) + 184c656aa4cSLars Poeschel 2 /* CKS + Postamble */) { 185c656aa4cSLars Poeschel skb_pull(skb, i); 186c656aa4cSLars Poeschel return 1; 187c656aa4cSLars Poeschel } 188c656aa4cSLars Poeschel 189c656aa4cSLars Poeschel break; 190c656aa4cSLars Poeschel default: /* normal information frame */ 191c656aa4cSLars Poeschel frame_len = std->datalen; 192c656aa4cSLars Poeschel if (skb->len >= frame_len + 193c656aa4cSLars Poeschel sizeof(struct pn533_std_frame) + 194c656aa4cSLars Poeschel 2 /* CKS + Postamble */) { 195c656aa4cSLars Poeschel skb_pull(skb, i); 196c656aa4cSLars Poeschel return 1; 197c656aa4cSLars Poeschel } 198c656aa4cSLars Poeschel 199c656aa4cSLars Poeschel break; 200c656aa4cSLars Poeschel } 201c656aa4cSLars Poeschel } 202c656aa4cSLars Poeschel 203c656aa4cSLars Poeschel return 0; 204c656aa4cSLars Poeschel } 205c656aa4cSLars Poeschel 206c656aa4cSLars Poeschel static int pn532_receive_buf(struct serdev_device *serdev, 207c656aa4cSLars Poeschel const unsigned char *data, size_t count) 208c656aa4cSLars Poeschel { 209c656aa4cSLars Poeschel struct pn532_uart_phy *dev = serdev_device_get_drvdata(serdev); 210c656aa4cSLars Poeschel size_t i; 211c656aa4cSLars Poeschel 212c656aa4cSLars Poeschel del_timer(&dev->cmd_timeout); 213c656aa4cSLars Poeschel for (i = 0; i < count; i++) { 214c656aa4cSLars Poeschel skb_put_u8(dev->recv_skb, *data++); 215c656aa4cSLars Poeschel if (!pn532_uart_rx_is_frame(dev->recv_skb)) 216c656aa4cSLars Poeschel continue; 217c656aa4cSLars Poeschel 218c656aa4cSLars Poeschel pn533_recv_frame(dev->priv, dev->recv_skb, 0); 219c656aa4cSLars Poeschel dev->recv_skb = alloc_skb(PN532_UART_SKB_BUFF_LEN, GFP_KERNEL); 220c656aa4cSLars Poeschel if (!dev->recv_skb) 221c656aa4cSLars Poeschel return 0; 222c656aa4cSLars Poeschel } 223c656aa4cSLars Poeschel 224c656aa4cSLars Poeschel return i; 225c656aa4cSLars Poeschel } 226c656aa4cSLars Poeschel 227be5f60d8SRikard Falkeborn static const struct serdev_device_ops pn532_serdev_ops = { 228c656aa4cSLars Poeschel .receive_buf = pn532_receive_buf, 229c656aa4cSLars Poeschel .write_wakeup = serdev_device_write_wakeup, 230c656aa4cSLars Poeschel }; 231c656aa4cSLars Poeschel 232c656aa4cSLars Poeschel static const struct of_device_id pn532_uart_of_match[] = { 233c656aa4cSLars Poeschel { .compatible = "nxp,pn532", }, 234c656aa4cSLars Poeschel {}, 235c656aa4cSLars Poeschel }; 236c656aa4cSLars Poeschel MODULE_DEVICE_TABLE(of, pn532_uart_of_match); 237c656aa4cSLars Poeschel 238c656aa4cSLars Poeschel static int pn532_uart_probe(struct serdev_device *serdev) 239c656aa4cSLars Poeschel { 240c656aa4cSLars Poeschel struct pn532_uart_phy *pn532; 241c656aa4cSLars Poeschel struct pn533 *priv; 242c656aa4cSLars Poeschel int err; 243c656aa4cSLars Poeschel 244c656aa4cSLars Poeschel err = -ENOMEM; 245c656aa4cSLars Poeschel pn532 = kzalloc(sizeof(*pn532), GFP_KERNEL); 246c656aa4cSLars Poeschel if (!pn532) 247c656aa4cSLars Poeschel goto err_exit; 248c656aa4cSLars Poeschel 249c656aa4cSLars Poeschel pn532->recv_skb = alloc_skb(PN532_UART_SKB_BUFF_LEN, GFP_KERNEL); 250c656aa4cSLars Poeschel if (!pn532->recv_skb) 251c656aa4cSLars Poeschel goto err_free; 252c656aa4cSLars Poeschel 253c656aa4cSLars Poeschel pn532->serdev = serdev; 254c656aa4cSLars Poeschel serdev_device_set_drvdata(serdev, pn532); 255c656aa4cSLars Poeschel serdev_device_set_client_ops(serdev, &pn532_serdev_ops); 256c656aa4cSLars Poeschel err = serdev_device_open(serdev); 257c656aa4cSLars Poeschel if (err) { 258c656aa4cSLars Poeschel dev_err(&serdev->dev, "Unable to open device\n"); 259c656aa4cSLars Poeschel goto err_skb; 260c656aa4cSLars Poeschel } 261c656aa4cSLars Poeschel 262c656aa4cSLars Poeschel err = serdev_device_set_baudrate(serdev, 115200); 263c656aa4cSLars Poeschel if (err != 115200) { 264c656aa4cSLars Poeschel err = -EINVAL; 265c656aa4cSLars Poeschel goto err_serdev; 266c656aa4cSLars Poeschel } 267c656aa4cSLars Poeschel 268c656aa4cSLars Poeschel serdev_device_set_flow_control(serdev, false); 269c656aa4cSLars Poeschel pn532->send_wakeup = PN532_SEND_WAKEUP; 270c656aa4cSLars Poeschel timer_setup(&pn532->cmd_timeout, pn532_cmd_timeout, 0); 271e4a5dc18SLars Poeschel priv = pn53x_common_init(PN533_DEVICE_PN532_AUTOPOLL, 272c656aa4cSLars Poeschel PN533_PROTO_REQ_ACK_RESP, 273c656aa4cSLars Poeschel pn532, &uart_phy_ops, NULL, 274c656aa4cSLars Poeschel &pn532->serdev->dev); 275c656aa4cSLars Poeschel if (IS_ERR(priv)) { 276c656aa4cSLars Poeschel err = PTR_ERR(priv); 277c656aa4cSLars Poeschel goto err_serdev; 278c656aa4cSLars Poeschel } 279c656aa4cSLars Poeschel 280c656aa4cSLars Poeschel pn532->priv = priv; 281c656aa4cSLars Poeschel err = pn533_finalize_setup(pn532->priv); 282c656aa4cSLars Poeschel if (err) 283c656aa4cSLars Poeschel goto err_clean; 284c656aa4cSLars Poeschel 285c656aa4cSLars Poeschel serdev_device_close(serdev); 286c656aa4cSLars Poeschel err = pn53x_register_nfc(priv, PN533_NO_TYPE_B_PROTOCOLS, &serdev->dev); 287c656aa4cSLars Poeschel if (err) { 288c656aa4cSLars Poeschel pn53x_common_clean(pn532->priv); 289c656aa4cSLars Poeschel goto err_skb; 290c656aa4cSLars Poeschel } 291c656aa4cSLars Poeschel 292c656aa4cSLars Poeschel return err; 293c656aa4cSLars Poeschel 294c656aa4cSLars Poeschel err_clean: 295c656aa4cSLars Poeschel pn53x_common_clean(pn532->priv); 296c656aa4cSLars Poeschel err_serdev: 297c656aa4cSLars Poeschel serdev_device_close(serdev); 298c656aa4cSLars Poeschel err_skb: 299c656aa4cSLars Poeschel kfree_skb(pn532->recv_skb); 300c656aa4cSLars Poeschel err_free: 301c656aa4cSLars Poeschel kfree(pn532); 302c656aa4cSLars Poeschel err_exit: 303c656aa4cSLars Poeschel return err; 304c656aa4cSLars Poeschel } 305c656aa4cSLars Poeschel 306c656aa4cSLars Poeschel static void pn532_uart_remove(struct serdev_device *serdev) 307c656aa4cSLars Poeschel { 308c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = serdev_device_get_drvdata(serdev); 309c656aa4cSLars Poeschel 310c656aa4cSLars Poeschel pn53x_unregister_nfc(pn532->priv); 311c656aa4cSLars Poeschel serdev_device_close(serdev); 312c656aa4cSLars Poeschel pn53x_common_clean(pn532->priv); 313*292a089dSSteven Rostedt (Google) timer_shutdown_sync(&pn532->cmd_timeout); 314c656aa4cSLars Poeschel kfree_skb(pn532->recv_skb); 315c656aa4cSLars Poeschel kfree(pn532); 316c656aa4cSLars Poeschel } 317c656aa4cSLars Poeschel 318c656aa4cSLars Poeschel static struct serdev_device_driver pn532_uart_driver = { 319c656aa4cSLars Poeschel .probe = pn532_uart_probe, 320c656aa4cSLars Poeschel .remove = pn532_uart_remove, 321c656aa4cSLars Poeschel .driver = { 322c656aa4cSLars Poeschel .name = "pn532_uart", 323a70bbbe3SKrzysztof Kozlowski .of_match_table = pn532_uart_of_match, 324c656aa4cSLars Poeschel }, 325c656aa4cSLars Poeschel }; 326c656aa4cSLars Poeschel 327c656aa4cSLars Poeschel module_serdev_device_driver(pn532_uart_driver); 328c656aa4cSLars Poeschel 329c656aa4cSLars Poeschel MODULE_AUTHOR("Lars Pöschel <poeschel@lemonage.de>"); 330c656aa4cSLars Poeschel MODULE_DESCRIPTION("PN532 UART driver"); 331c656aa4cSLars Poeschel MODULE_LICENSE("GPL"); 332