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 103c656aa4cSLars Poeschel static void pn532_dev_up(struct pn533 *dev) 104c656aa4cSLars Poeschel { 105c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = dev->phy; 106c656aa4cSLars Poeschel 107c656aa4cSLars Poeschel serdev_device_open(pn532->serdev); 108c656aa4cSLars Poeschel pn532->send_wakeup = PN532_SEND_LAST_WAKEUP; 109c656aa4cSLars Poeschel } 110c656aa4cSLars Poeschel 111c656aa4cSLars Poeschel static void pn532_dev_down(struct pn533 *dev) 112c656aa4cSLars Poeschel { 113c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = dev->phy; 114c656aa4cSLars Poeschel 115c656aa4cSLars Poeschel serdev_device_close(pn532->serdev); 116c656aa4cSLars Poeschel pn532->send_wakeup = PN532_SEND_WAKEUP; 117c656aa4cSLars Poeschel } 118c656aa4cSLars Poeschel 119c656aa4cSLars Poeschel static struct pn533_phy_ops uart_phy_ops = { 120c656aa4cSLars Poeschel .send_frame = pn532_uart_send_frame, 121c656aa4cSLars Poeschel .send_ack = pn532_uart_send_ack, 122c656aa4cSLars Poeschel .abort_cmd = pn532_uart_abort_cmd, 123c656aa4cSLars Poeschel .dev_up = pn532_dev_up, 124c656aa4cSLars Poeschel .dev_down = pn532_dev_down, 125c656aa4cSLars Poeschel }; 126c656aa4cSLars Poeschel 127c656aa4cSLars Poeschel static void pn532_cmd_timeout(struct timer_list *t) 128c656aa4cSLars Poeschel { 129c656aa4cSLars Poeschel struct pn532_uart_phy *dev = from_timer(dev, t, cmd_timeout); 130c656aa4cSLars Poeschel 131c656aa4cSLars Poeschel pn532_uart_send_frame(dev->priv, dev->cur_out_buf); 132c656aa4cSLars Poeschel } 133c656aa4cSLars Poeschel 134c656aa4cSLars Poeschel /* 135c656aa4cSLars Poeschel * scans the buffer if it contains a pn532 frame. It is not checked if the 136c656aa4cSLars Poeschel * frame is really valid. This is later done with pn533_rx_frame_is_valid. 137c656aa4cSLars Poeschel * This is useful for malformed or errornous transmitted frames. Adjusts the 138c656aa4cSLars Poeschel * bufferposition where the frame starts, since pn533_recv_frame expects a 139c656aa4cSLars Poeschel * well formed frame. 140c656aa4cSLars Poeschel */ 141c656aa4cSLars Poeschel static int pn532_uart_rx_is_frame(struct sk_buff *skb) 142c656aa4cSLars Poeschel { 143c656aa4cSLars Poeschel struct pn533_std_frame *std; 144c656aa4cSLars Poeschel struct pn533_ext_frame *ext; 145c656aa4cSLars Poeschel u16 frame_len; 146c656aa4cSLars Poeschel int i; 147c656aa4cSLars Poeschel 148c656aa4cSLars Poeschel for (i = 0; i + PN533_STD_FRAME_ACK_SIZE <= skb->len; i++) { 149c656aa4cSLars Poeschel std = (struct pn533_std_frame *)&skb->data[i]; 150c656aa4cSLars Poeschel /* search start code */ 151c656aa4cSLars Poeschel if (std->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF)) 152c656aa4cSLars Poeschel continue; 153c656aa4cSLars Poeschel 154c656aa4cSLars Poeschel /* frame type */ 155c656aa4cSLars Poeschel switch (std->datalen) { 156c656aa4cSLars Poeschel case PN533_FRAME_DATALEN_ACK: 157c656aa4cSLars Poeschel if (std->datalen_checksum == 0xff) { 158c656aa4cSLars Poeschel skb_pull(skb, i); 159c656aa4cSLars Poeschel return 1; 160c656aa4cSLars Poeschel } 161c656aa4cSLars Poeschel 162c656aa4cSLars Poeschel break; 163c656aa4cSLars Poeschel case PN533_FRAME_DATALEN_ERROR: 164c656aa4cSLars Poeschel if ((std->datalen_checksum == 0xff) && 165c656aa4cSLars Poeschel (skb->len >= 166c656aa4cSLars Poeschel PN533_STD_ERROR_FRAME_SIZE)) { 167c656aa4cSLars Poeschel skb_pull(skb, i); 168c656aa4cSLars Poeschel return 1; 169c656aa4cSLars Poeschel } 170c656aa4cSLars Poeschel 171c656aa4cSLars Poeschel break; 172c656aa4cSLars Poeschel case PN533_FRAME_DATALEN_EXTENDED: 173c656aa4cSLars Poeschel ext = (struct pn533_ext_frame *)&skb->data[i]; 174c656aa4cSLars Poeschel frame_len = be16_to_cpu(ext->datalen); 175c656aa4cSLars Poeschel if (skb->len >= frame_len + 176c656aa4cSLars Poeschel sizeof(struct pn533_ext_frame) + 177c656aa4cSLars Poeschel 2 /* CKS + Postamble */) { 178c656aa4cSLars Poeschel skb_pull(skb, i); 179c656aa4cSLars Poeschel return 1; 180c656aa4cSLars Poeschel } 181c656aa4cSLars Poeschel 182c656aa4cSLars Poeschel break; 183c656aa4cSLars Poeschel default: /* normal information frame */ 184c656aa4cSLars Poeschel frame_len = std->datalen; 185c656aa4cSLars Poeschel if (skb->len >= frame_len + 186c656aa4cSLars Poeschel sizeof(struct pn533_std_frame) + 187c656aa4cSLars Poeschel 2 /* CKS + Postamble */) { 188c656aa4cSLars Poeschel skb_pull(skb, i); 189c656aa4cSLars Poeschel return 1; 190c656aa4cSLars Poeschel } 191c656aa4cSLars Poeschel 192c656aa4cSLars Poeschel break; 193c656aa4cSLars Poeschel } 194c656aa4cSLars Poeschel } 195c656aa4cSLars Poeschel 196c656aa4cSLars Poeschel return 0; 197c656aa4cSLars Poeschel } 198c656aa4cSLars Poeschel 199c656aa4cSLars Poeschel static int pn532_receive_buf(struct serdev_device *serdev, 200c656aa4cSLars Poeschel const unsigned char *data, size_t count) 201c656aa4cSLars Poeschel { 202c656aa4cSLars Poeschel struct pn532_uart_phy *dev = serdev_device_get_drvdata(serdev); 203c656aa4cSLars Poeschel size_t i; 204c656aa4cSLars Poeschel 205c656aa4cSLars Poeschel del_timer(&dev->cmd_timeout); 206c656aa4cSLars Poeschel for (i = 0; i < count; i++) { 207c656aa4cSLars Poeschel skb_put_u8(dev->recv_skb, *data++); 208c656aa4cSLars Poeschel if (!pn532_uart_rx_is_frame(dev->recv_skb)) 209c656aa4cSLars Poeschel continue; 210c656aa4cSLars Poeschel 211c656aa4cSLars Poeschel pn533_recv_frame(dev->priv, dev->recv_skb, 0); 212c656aa4cSLars Poeschel dev->recv_skb = alloc_skb(PN532_UART_SKB_BUFF_LEN, GFP_KERNEL); 213c656aa4cSLars Poeschel if (!dev->recv_skb) 214c656aa4cSLars Poeschel return 0; 215c656aa4cSLars Poeschel } 216c656aa4cSLars Poeschel 217c656aa4cSLars Poeschel return i; 218c656aa4cSLars Poeschel } 219c656aa4cSLars Poeschel 220c656aa4cSLars Poeschel static struct serdev_device_ops pn532_serdev_ops = { 221c656aa4cSLars Poeschel .receive_buf = pn532_receive_buf, 222c656aa4cSLars Poeschel .write_wakeup = serdev_device_write_wakeup, 223c656aa4cSLars Poeschel }; 224c656aa4cSLars Poeschel 225c656aa4cSLars Poeschel static const struct of_device_id pn532_uart_of_match[] = { 226c656aa4cSLars Poeschel { .compatible = "nxp,pn532", }, 227c656aa4cSLars Poeschel {}, 228c656aa4cSLars Poeschel }; 229c656aa4cSLars Poeschel MODULE_DEVICE_TABLE(of, pn532_uart_of_match); 230c656aa4cSLars Poeschel 231c656aa4cSLars Poeschel static int pn532_uart_probe(struct serdev_device *serdev) 232c656aa4cSLars Poeschel { 233c656aa4cSLars Poeschel struct pn532_uart_phy *pn532; 234c656aa4cSLars Poeschel struct pn533 *priv; 235c656aa4cSLars Poeschel int err; 236c656aa4cSLars Poeschel 237c656aa4cSLars Poeschel err = -ENOMEM; 238c656aa4cSLars Poeschel pn532 = kzalloc(sizeof(*pn532), GFP_KERNEL); 239c656aa4cSLars Poeschel if (!pn532) 240c656aa4cSLars Poeschel goto err_exit; 241c656aa4cSLars Poeschel 242c656aa4cSLars Poeschel pn532->recv_skb = alloc_skb(PN532_UART_SKB_BUFF_LEN, GFP_KERNEL); 243c656aa4cSLars Poeschel if (!pn532->recv_skb) 244c656aa4cSLars Poeschel goto err_free; 245c656aa4cSLars Poeschel 246c656aa4cSLars Poeschel pn532->serdev = serdev; 247c656aa4cSLars Poeschel serdev_device_set_drvdata(serdev, pn532); 248c656aa4cSLars Poeschel serdev_device_set_client_ops(serdev, &pn532_serdev_ops); 249c656aa4cSLars Poeschel err = serdev_device_open(serdev); 250c656aa4cSLars Poeschel if (err) { 251c656aa4cSLars Poeschel dev_err(&serdev->dev, "Unable to open device\n"); 252c656aa4cSLars Poeschel goto err_skb; 253c656aa4cSLars Poeschel } 254c656aa4cSLars Poeschel 255c656aa4cSLars Poeschel err = serdev_device_set_baudrate(serdev, 115200); 256c656aa4cSLars Poeschel if (err != 115200) { 257c656aa4cSLars Poeschel err = -EINVAL; 258c656aa4cSLars Poeschel goto err_serdev; 259c656aa4cSLars Poeschel } 260c656aa4cSLars Poeschel 261c656aa4cSLars Poeschel serdev_device_set_flow_control(serdev, false); 262c656aa4cSLars Poeschel pn532->send_wakeup = PN532_SEND_WAKEUP; 263c656aa4cSLars Poeschel timer_setup(&pn532->cmd_timeout, pn532_cmd_timeout, 0); 264*e4a5dc18SLars Poeschel priv = pn53x_common_init(PN533_DEVICE_PN532_AUTOPOLL, 265c656aa4cSLars Poeschel PN533_PROTO_REQ_ACK_RESP, 266c656aa4cSLars Poeschel pn532, &uart_phy_ops, NULL, 267c656aa4cSLars Poeschel &pn532->serdev->dev); 268c656aa4cSLars Poeschel if (IS_ERR(priv)) { 269c656aa4cSLars Poeschel err = PTR_ERR(priv); 270c656aa4cSLars Poeschel goto err_serdev; 271c656aa4cSLars Poeschel } 272c656aa4cSLars Poeschel 273c656aa4cSLars Poeschel pn532->priv = priv; 274c656aa4cSLars Poeschel err = pn533_finalize_setup(pn532->priv); 275c656aa4cSLars Poeschel if (err) 276c656aa4cSLars Poeschel goto err_clean; 277c656aa4cSLars Poeschel 278c656aa4cSLars Poeschel serdev_device_close(serdev); 279c656aa4cSLars Poeschel err = pn53x_register_nfc(priv, PN533_NO_TYPE_B_PROTOCOLS, &serdev->dev); 280c656aa4cSLars Poeschel if (err) { 281c656aa4cSLars Poeschel pn53x_common_clean(pn532->priv); 282c656aa4cSLars Poeschel goto err_skb; 283c656aa4cSLars Poeschel } 284c656aa4cSLars Poeschel 285c656aa4cSLars Poeschel return err; 286c656aa4cSLars Poeschel 287c656aa4cSLars Poeschel err_clean: 288c656aa4cSLars Poeschel pn53x_common_clean(pn532->priv); 289c656aa4cSLars Poeschel err_serdev: 290c656aa4cSLars Poeschel serdev_device_close(serdev); 291c656aa4cSLars Poeschel err_skb: 292c656aa4cSLars Poeschel kfree_skb(pn532->recv_skb); 293c656aa4cSLars Poeschel err_free: 294c656aa4cSLars Poeschel kfree(pn532); 295c656aa4cSLars Poeschel err_exit: 296c656aa4cSLars Poeschel return err; 297c656aa4cSLars Poeschel } 298c656aa4cSLars Poeschel 299c656aa4cSLars Poeschel static void pn532_uart_remove(struct serdev_device *serdev) 300c656aa4cSLars Poeschel { 301c656aa4cSLars Poeschel struct pn532_uart_phy *pn532 = serdev_device_get_drvdata(serdev); 302c656aa4cSLars Poeschel 303c656aa4cSLars Poeschel pn53x_unregister_nfc(pn532->priv); 304c656aa4cSLars Poeschel serdev_device_close(serdev); 305c656aa4cSLars Poeschel pn53x_common_clean(pn532->priv); 306c656aa4cSLars Poeschel kfree_skb(pn532->recv_skb); 307c656aa4cSLars Poeschel kfree(pn532); 308c656aa4cSLars Poeschel } 309c656aa4cSLars Poeschel 310c656aa4cSLars Poeschel static struct serdev_device_driver pn532_uart_driver = { 311c656aa4cSLars Poeschel .probe = pn532_uart_probe, 312c656aa4cSLars Poeschel .remove = pn532_uart_remove, 313c656aa4cSLars Poeschel .driver = { 314c656aa4cSLars Poeschel .name = "pn532_uart", 315c656aa4cSLars Poeschel .of_match_table = of_match_ptr(pn532_uart_of_match), 316c656aa4cSLars Poeschel }, 317c656aa4cSLars Poeschel }; 318c656aa4cSLars Poeschel 319c656aa4cSLars Poeschel module_serdev_device_driver(pn532_uart_driver); 320c656aa4cSLars Poeschel 321c656aa4cSLars Poeschel MODULE_AUTHOR("Lars Pöschel <poeschel@lemonage.de>"); 322c656aa4cSLars Poeschel MODULE_DESCRIPTION("PN532 UART driver"); 323c656aa4cSLars Poeschel MODULE_LICENSE("GPL"); 324