18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * I2C Link Layer for ST21NFCA HCI based Driver 48c2ecf20Sopenharmony_ci * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/crc-ccitt.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/i2c.h> 128c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h> 138c2ecf20Sopenharmony_ci#include <linux/of_irq.h> 148c2ecf20Sopenharmony_ci#include <linux/of_gpio.h> 158c2ecf20Sopenharmony_ci#include <linux/acpi.h> 168c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 178c2ecf20Sopenharmony_ci#include <linux/delay.h> 188c2ecf20Sopenharmony_ci#include <linux/nfc.h> 198c2ecf20Sopenharmony_ci#include <linux/firmware.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <asm/unaligned.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <net/nfc/hci.h> 248c2ecf20Sopenharmony_ci#include <net/nfc/llc.h> 258c2ecf20Sopenharmony_ci#include <net/nfc/nfc.h> 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include "st21nfca.h" 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* 308c2ecf20Sopenharmony_ci * Every frame starts with ST21NFCA_SOF_EOF and ends with ST21NFCA_SOF_EOF. 318c2ecf20Sopenharmony_ci * Because ST21NFCA_SOF_EOF is a possible data value, there is a mecanism 328c2ecf20Sopenharmony_ci * called byte stuffing has been introduced. 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci * if byte == ST21NFCA_SOF_EOF or ST21NFCA_ESCAPE_BYTE_STUFFING 358c2ecf20Sopenharmony_ci * - insert ST21NFCA_ESCAPE_BYTE_STUFFING (escape byte) 368c2ecf20Sopenharmony_ci * - xor byte with ST21NFCA_BYTE_STUFFING_MASK 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci#define ST21NFCA_SOF_EOF 0x7e 398c2ecf20Sopenharmony_ci#define ST21NFCA_BYTE_STUFFING_MASK 0x20 408c2ecf20Sopenharmony_ci#define ST21NFCA_ESCAPE_BYTE_STUFFING 0x7d 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* SOF + 00 */ 438c2ecf20Sopenharmony_ci#define ST21NFCA_FRAME_HEADROOM 2 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci/* 2 bytes crc + EOF */ 468c2ecf20Sopenharmony_ci#define ST21NFCA_FRAME_TAILROOM 3 478c2ecf20Sopenharmony_ci#define IS_START_OF_FRAME(buf) (buf[0] == ST21NFCA_SOF_EOF && \ 488c2ecf20Sopenharmony_ci buf[1] == 0) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci" 518c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_I2C_DRIVER_NAME "st21nfca_hci_i2c" 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistruct st21nfca_i2c_phy { 548c2ecf20Sopenharmony_ci struct i2c_client *i2c_dev; 558c2ecf20Sopenharmony_ci struct nfc_hci_dev *hdev; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci struct gpio_desc *gpiod_ena; 588c2ecf20Sopenharmony_ci struct st21nfca_se_status se_status; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci struct sk_buff *pending_skb; 618c2ecf20Sopenharmony_ci int current_read_len; 628c2ecf20Sopenharmony_ci /* 638c2ecf20Sopenharmony_ci * crc might have fail because i2c macro 648c2ecf20Sopenharmony_ci * is disable due to other interface activity 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ci int crc_trials; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci int powered; 698c2ecf20Sopenharmony_ci int run_mode; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* 728c2ecf20Sopenharmony_ci * < 0 if hardware error occured (e.g. i2c err) 738c2ecf20Sopenharmony_ci * and prevents normal operation. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci int hard_fault; 768c2ecf20Sopenharmony_ci struct mutex phy_lock; 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic u8 len_seq[] = { 16, 24, 12, 29 }; 808c2ecf20Sopenharmony_cistatic u16 wait_tab[] = { 2, 3, 5, 15, 20, 40}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#define I2C_DUMP_SKB(info, skb) \ 838c2ecf20Sopenharmony_cido { \ 848c2ecf20Sopenharmony_ci pr_debug("%s:\n", info); \ 858c2ecf20Sopenharmony_ci print_hex_dump(KERN_DEBUG, "i2c: ", DUMP_PREFIX_OFFSET, \ 868c2ecf20Sopenharmony_ci 16, 1, (skb)->data, (skb)->len, 0); \ 878c2ecf20Sopenharmony_ci} while (0) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci/* 908c2ecf20Sopenharmony_ci * In order to get the CLF in a known state we generate an internal reboot 918c2ecf20Sopenharmony_ci * using a proprietary command. 928c2ecf20Sopenharmony_ci * Once the reboot is completed, we expect to receive a ST21NFCA_SOF_EOF 938c2ecf20Sopenharmony_ci * fill buffer. 948c2ecf20Sopenharmony_ci */ 958c2ecf20Sopenharmony_cistatic int st21nfca_hci_platform_init(struct st21nfca_i2c_phy *phy) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci u16 wait_reboot[] = { 50, 300, 1000 }; 988c2ecf20Sopenharmony_ci char reboot_cmd[] = { 0x7E, 0x66, 0x48, 0xF6, 0x7E }; 998c2ecf20Sopenharmony_ci u8 tmp[ST21NFCA_HCI_LLC_MAX_SIZE]; 1008c2ecf20Sopenharmony_ci int i, r = -1; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(wait_reboot) && r < 0; i++) { 1038c2ecf20Sopenharmony_ci r = i2c_master_send(phy->i2c_dev, reboot_cmd, 1048c2ecf20Sopenharmony_ci sizeof(reboot_cmd)); 1058c2ecf20Sopenharmony_ci if (r < 0) 1068c2ecf20Sopenharmony_ci msleep(wait_reboot[i]); 1078c2ecf20Sopenharmony_ci } 1088c2ecf20Sopenharmony_ci if (r < 0) 1098c2ecf20Sopenharmony_ci return r; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci /* CLF is spending about 20ms to do an internal reboot */ 1128c2ecf20Sopenharmony_ci msleep(20); 1138c2ecf20Sopenharmony_ci r = -1; 1148c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(wait_reboot) && r < 0; i++) { 1158c2ecf20Sopenharmony_ci r = i2c_master_recv(phy->i2c_dev, tmp, 1168c2ecf20Sopenharmony_ci ST21NFCA_HCI_LLC_MAX_SIZE); 1178c2ecf20Sopenharmony_ci if (r < 0) 1188c2ecf20Sopenharmony_ci msleep(wait_reboot[i]); 1198c2ecf20Sopenharmony_ci } 1208c2ecf20Sopenharmony_ci if (r < 0) 1218c2ecf20Sopenharmony_ci return r; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci for (i = 0; i < ST21NFCA_HCI_LLC_MAX_SIZE && 1248c2ecf20Sopenharmony_ci tmp[i] == ST21NFCA_SOF_EOF; i++) 1258c2ecf20Sopenharmony_ci ; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci if (r != ST21NFCA_HCI_LLC_MAX_SIZE) 1288c2ecf20Sopenharmony_ci return -ENODEV; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci usleep_range(1000, 1500); 1318c2ecf20Sopenharmony_ci return 0; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic int st21nfca_hci_i2c_enable(void *phy_id) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci struct st21nfca_i2c_phy *phy = phy_id; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci gpiod_set_value(phy->gpiod_ena, 1); 1398c2ecf20Sopenharmony_ci phy->powered = 1; 1408c2ecf20Sopenharmony_ci phy->run_mode = ST21NFCA_HCI_MODE; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci usleep_range(10000, 15000); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci return 0; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistatic void st21nfca_hci_i2c_disable(void *phy_id) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci struct st21nfca_i2c_phy *phy = phy_id; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci gpiod_set_value(phy->gpiod_ena, 0); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci phy->powered = 0; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic void st21nfca_hci_add_len_crc(struct sk_buff *skb) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci u16 crc; 1598c2ecf20Sopenharmony_ci u8 tmp; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci *(u8 *)skb_push(skb, 1) = 0; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci crc = crc_ccitt(0xffff, skb->data, skb->len); 1648c2ecf20Sopenharmony_ci crc = ~crc; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci tmp = crc & 0x00ff; 1678c2ecf20Sopenharmony_ci skb_put_u8(skb, tmp); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci tmp = (crc >> 8) & 0x00ff; 1708c2ecf20Sopenharmony_ci skb_put_u8(skb, tmp); 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic void st21nfca_hci_remove_len_crc(struct sk_buff *skb) 1748c2ecf20Sopenharmony_ci{ 1758c2ecf20Sopenharmony_ci skb_pull(skb, ST21NFCA_FRAME_HEADROOM); 1768c2ecf20Sopenharmony_ci skb_trim(skb, skb->len - ST21NFCA_FRAME_TAILROOM); 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci/* 1808c2ecf20Sopenharmony_ci * Writing a frame must not return the number of written bytes. 1818c2ecf20Sopenharmony_ci * It must return either zero for success, or <0 for error. 1828c2ecf20Sopenharmony_ci * In addition, it must not alter the skb 1838c2ecf20Sopenharmony_ci */ 1848c2ecf20Sopenharmony_cistatic int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci int r = -1, i, j; 1878c2ecf20Sopenharmony_ci struct st21nfca_i2c_phy *phy = phy_id; 1888c2ecf20Sopenharmony_ci struct i2c_client *client = phy->i2c_dev; 1898c2ecf20Sopenharmony_ci u8 tmp[ST21NFCA_HCI_LLC_MAX_SIZE * 2]; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci I2C_DUMP_SKB("st21nfca_hci_i2c_write", skb); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci if (phy->hard_fault != 0) 1948c2ecf20Sopenharmony_ci return phy->hard_fault; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci /* 1978c2ecf20Sopenharmony_ci * Compute CRC before byte stuffing computation on frame 1988c2ecf20Sopenharmony_ci * Note st21nfca_hci_add_len_crc is doing a byte stuffing 1998c2ecf20Sopenharmony_ci * on its own value 2008c2ecf20Sopenharmony_ci */ 2018c2ecf20Sopenharmony_ci st21nfca_hci_add_len_crc(skb); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci /* add ST21NFCA_SOF_EOF on tail */ 2048c2ecf20Sopenharmony_ci skb_put_u8(skb, ST21NFCA_SOF_EOF); 2058c2ecf20Sopenharmony_ci /* add ST21NFCA_SOF_EOF on head */ 2068c2ecf20Sopenharmony_ci *(u8 *)skb_push(skb, 1) = ST21NFCA_SOF_EOF; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci /* 2098c2ecf20Sopenharmony_ci * Compute byte stuffing 2108c2ecf20Sopenharmony_ci * if byte == ST21NFCA_SOF_EOF or ST21NFCA_ESCAPE_BYTE_STUFFING 2118c2ecf20Sopenharmony_ci * insert ST21NFCA_ESCAPE_BYTE_STUFFING (escape byte) 2128c2ecf20Sopenharmony_ci * xor byte with ST21NFCA_BYTE_STUFFING_MASK 2138c2ecf20Sopenharmony_ci */ 2148c2ecf20Sopenharmony_ci tmp[0] = skb->data[0]; 2158c2ecf20Sopenharmony_ci for (i = 1, j = 1; i < skb->len - 1; i++, j++) { 2168c2ecf20Sopenharmony_ci if (skb->data[i] == ST21NFCA_SOF_EOF 2178c2ecf20Sopenharmony_ci || skb->data[i] == ST21NFCA_ESCAPE_BYTE_STUFFING) { 2188c2ecf20Sopenharmony_ci tmp[j] = ST21NFCA_ESCAPE_BYTE_STUFFING; 2198c2ecf20Sopenharmony_ci j++; 2208c2ecf20Sopenharmony_ci tmp[j] = skb->data[i] ^ ST21NFCA_BYTE_STUFFING_MASK; 2218c2ecf20Sopenharmony_ci } else { 2228c2ecf20Sopenharmony_ci tmp[j] = skb->data[i]; 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci tmp[j] = skb->data[i]; 2268c2ecf20Sopenharmony_ci j++; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci /* 2298c2ecf20Sopenharmony_ci * Manage sleep mode 2308c2ecf20Sopenharmony_ci * Try 3 times to send data with delay between each 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_ci mutex_lock(&phy->phy_lock); 2338c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(wait_tab) && r < 0; i++) { 2348c2ecf20Sopenharmony_ci r = i2c_master_send(client, tmp, j); 2358c2ecf20Sopenharmony_ci if (r < 0) 2368c2ecf20Sopenharmony_ci msleep(wait_tab[i]); 2378c2ecf20Sopenharmony_ci } 2388c2ecf20Sopenharmony_ci mutex_unlock(&phy->phy_lock); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if (r >= 0) { 2418c2ecf20Sopenharmony_ci if (r != j) 2428c2ecf20Sopenharmony_ci r = -EREMOTEIO; 2438c2ecf20Sopenharmony_ci else 2448c2ecf20Sopenharmony_ci r = 0; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci st21nfca_hci_remove_len_crc(skb); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci return r; 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic int get_frame_size(u8 *buf, int buflen) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci int len = 0; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci if (buf[len + 1] == ST21NFCA_SOF_EOF) 2578c2ecf20Sopenharmony_ci return 0; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci for (len = 1; len < buflen && buf[len] != ST21NFCA_SOF_EOF; len++) 2608c2ecf20Sopenharmony_ci ; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci return len; 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_cistatic int check_crc(u8 *buf, int buflen) 2668c2ecf20Sopenharmony_ci{ 2678c2ecf20Sopenharmony_ci u16 crc; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci crc = crc_ccitt(0xffff, buf, buflen - 2); 2708c2ecf20Sopenharmony_ci crc = ~crc; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci if (buf[buflen - 2] != (crc & 0xff) || buf[buflen - 1] != (crc >> 8)) { 2738c2ecf20Sopenharmony_ci pr_err(ST21NFCA_HCI_DRIVER_NAME 2748c2ecf20Sopenharmony_ci ": CRC error 0x%x != 0x%x 0x%x\n", crc, buf[buflen - 1], 2758c2ecf20Sopenharmony_ci buf[buflen - 2]); 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); 2788c2ecf20Sopenharmony_ci print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, 2798c2ecf20Sopenharmony_ci 16, 2, buf, buflen, false); 2808c2ecf20Sopenharmony_ci return -EPERM; 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci return 0; 2838c2ecf20Sopenharmony_ci} 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci/* 2868c2ecf20Sopenharmony_ci * Prepare received data for upper layer. 2878c2ecf20Sopenharmony_ci * Received data include byte stuffing, crc and sof/eof 2888c2ecf20Sopenharmony_ci * which is not usable by hci part. 2898c2ecf20Sopenharmony_ci * returns: 2908c2ecf20Sopenharmony_ci * frame size without sof/eof, header and byte stuffing 2918c2ecf20Sopenharmony_ci * -EBADMSG : frame was incorrect and discarded 2928c2ecf20Sopenharmony_ci */ 2938c2ecf20Sopenharmony_cistatic int st21nfca_hci_i2c_repack(struct sk_buff *skb) 2948c2ecf20Sopenharmony_ci{ 2958c2ecf20Sopenharmony_ci int i, j, r, size; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci if (skb->len < 1 || (skb->len > 1 && skb->data[1] != 0)) 2988c2ecf20Sopenharmony_ci return -EBADMSG; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci size = get_frame_size(skb->data, skb->len); 3018c2ecf20Sopenharmony_ci if (size > 0) { 3028c2ecf20Sopenharmony_ci skb_trim(skb, size); 3038c2ecf20Sopenharmony_ci /* remove ST21NFCA byte stuffing for upper layer */ 3048c2ecf20Sopenharmony_ci for (i = 1, j = 0; i < skb->len; i++) { 3058c2ecf20Sopenharmony_ci if (skb->data[i + j] == 3068c2ecf20Sopenharmony_ci (u8) ST21NFCA_ESCAPE_BYTE_STUFFING) { 3078c2ecf20Sopenharmony_ci skb->data[i] = skb->data[i + j + 1] 3088c2ecf20Sopenharmony_ci | ST21NFCA_BYTE_STUFFING_MASK; 3098c2ecf20Sopenharmony_ci i++; 3108c2ecf20Sopenharmony_ci j++; 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci skb->data[i] = skb->data[i + j]; 3138c2ecf20Sopenharmony_ci } 3148c2ecf20Sopenharmony_ci /* remove byte stuffing useless byte */ 3158c2ecf20Sopenharmony_ci skb_trim(skb, i - j); 3168c2ecf20Sopenharmony_ci /* remove ST21NFCA_SOF_EOF from head */ 3178c2ecf20Sopenharmony_ci skb_pull(skb, 1); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci r = check_crc(skb->data, skb->len); 3208c2ecf20Sopenharmony_ci if (r != 0) { 3218c2ecf20Sopenharmony_ci i = 0; 3228c2ecf20Sopenharmony_ci return -EBADMSG; 3238c2ecf20Sopenharmony_ci } 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci /* remove headbyte */ 3268c2ecf20Sopenharmony_ci skb_pull(skb, 1); 3278c2ecf20Sopenharmony_ci /* remove crc. Byte Stuffing is already removed here */ 3288c2ecf20Sopenharmony_ci skb_trim(skb, skb->len - 2); 3298c2ecf20Sopenharmony_ci return skb->len; 3308c2ecf20Sopenharmony_ci } 3318c2ecf20Sopenharmony_ci return 0; 3328c2ecf20Sopenharmony_ci} 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci/* 3358c2ecf20Sopenharmony_ci * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees 3368c2ecf20Sopenharmony_ci * that i2c bus will be flushed and that next read will start on a new frame. 3378c2ecf20Sopenharmony_ci * returned skb contains only LLC header and payload. 3388c2ecf20Sopenharmony_ci * returns: 3398c2ecf20Sopenharmony_ci * frame size : if received frame is complete (find ST21NFCA_SOF_EOF at 3408c2ecf20Sopenharmony_ci * end of read) 3418c2ecf20Sopenharmony_ci * -EAGAIN : if received frame is incomplete (not find ST21NFCA_SOF_EOF 3428c2ecf20Sopenharmony_ci * at end of read) 3438c2ecf20Sopenharmony_ci * -EREMOTEIO : i2c read error (fatal) 3448c2ecf20Sopenharmony_ci * -EBADMSG : frame was incorrect and discarded 3458c2ecf20Sopenharmony_ci * (value returned from st21nfca_hci_i2c_repack) 3468c2ecf20Sopenharmony_ci * -EIO : if no ST21NFCA_SOF_EOF is found after reaching 3478c2ecf20Sopenharmony_ci * the read length end sequence 3488c2ecf20Sopenharmony_ci */ 3498c2ecf20Sopenharmony_cistatic int st21nfca_hci_i2c_read(struct st21nfca_i2c_phy *phy, 3508c2ecf20Sopenharmony_ci struct sk_buff *skb) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci int r, i; 3538c2ecf20Sopenharmony_ci u8 len; 3548c2ecf20Sopenharmony_ci u8 buf[ST21NFCA_HCI_LLC_MAX_PAYLOAD]; 3558c2ecf20Sopenharmony_ci struct i2c_client *client = phy->i2c_dev; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci if (phy->current_read_len < ARRAY_SIZE(len_seq)) { 3588c2ecf20Sopenharmony_ci len = len_seq[phy->current_read_len]; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci /* 3618c2ecf20Sopenharmony_ci * Add retry mecanism 3628c2ecf20Sopenharmony_ci * Operation on I2C interface may fail in case of operation on 3638c2ecf20Sopenharmony_ci * RF or SWP interface 3648c2ecf20Sopenharmony_ci */ 3658c2ecf20Sopenharmony_ci r = 0; 3668c2ecf20Sopenharmony_ci mutex_lock(&phy->phy_lock); 3678c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(wait_tab) && r <= 0; i++) { 3688c2ecf20Sopenharmony_ci r = i2c_master_recv(client, buf, len); 3698c2ecf20Sopenharmony_ci if (r < 0) 3708c2ecf20Sopenharmony_ci msleep(wait_tab[i]); 3718c2ecf20Sopenharmony_ci } 3728c2ecf20Sopenharmony_ci mutex_unlock(&phy->phy_lock); 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci if (r != len) { 3758c2ecf20Sopenharmony_ci phy->current_read_len = 0; 3768c2ecf20Sopenharmony_ci return -EREMOTEIO; 3778c2ecf20Sopenharmony_ci } 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci /* 3808c2ecf20Sopenharmony_ci * The first read sequence does not start with SOF. 3818c2ecf20Sopenharmony_ci * Data is corrupeted so we drop it. 3828c2ecf20Sopenharmony_ci */ 3838c2ecf20Sopenharmony_ci if (!phy->current_read_len && !IS_START_OF_FRAME(buf)) { 3848c2ecf20Sopenharmony_ci skb_trim(skb, 0); 3858c2ecf20Sopenharmony_ci phy->current_read_len = 0; 3868c2ecf20Sopenharmony_ci return -EIO; 3878c2ecf20Sopenharmony_ci } else if (phy->current_read_len && IS_START_OF_FRAME(buf)) { 3888c2ecf20Sopenharmony_ci /* 3898c2ecf20Sopenharmony_ci * Previous frame transmission was interrupted and 3908c2ecf20Sopenharmony_ci * the frame got repeated. 3918c2ecf20Sopenharmony_ci * Received frame start with ST21NFCA_SOF_EOF + 00. 3928c2ecf20Sopenharmony_ci */ 3938c2ecf20Sopenharmony_ci skb_trim(skb, 0); 3948c2ecf20Sopenharmony_ci phy->current_read_len = 0; 3958c2ecf20Sopenharmony_ci } 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci skb_put_data(skb, buf, len); 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci if (skb->data[skb->len - 1] == ST21NFCA_SOF_EOF) { 4008c2ecf20Sopenharmony_ci phy->current_read_len = 0; 4018c2ecf20Sopenharmony_ci return st21nfca_hci_i2c_repack(skb); 4028c2ecf20Sopenharmony_ci } 4038c2ecf20Sopenharmony_ci phy->current_read_len++; 4048c2ecf20Sopenharmony_ci return -EAGAIN; 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci return -EIO; 4078c2ecf20Sopenharmony_ci} 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci/* 4108c2ecf20Sopenharmony_ci * Reads an shdlc frame from the chip. This is not as straightforward as it 4118c2ecf20Sopenharmony_ci * seems. The frame format is data-crc, and corruption can occur anywhere 4128c2ecf20Sopenharmony_ci * while transiting on i2c bus, such that we could read an invalid data. 4138c2ecf20Sopenharmony_ci * The tricky case is when we read a corrupted data or crc. We must detect 4148c2ecf20Sopenharmony_ci * this here in order to determine that data can be transmitted to the hci 4158c2ecf20Sopenharmony_ci * core. This is the reason why we check the crc here. 4168c2ecf20Sopenharmony_ci * The CLF will repeat a frame until we send a RR on that frame. 4178c2ecf20Sopenharmony_ci * 4188c2ecf20Sopenharmony_ci * On ST21NFCA, IRQ goes in idle when read starts. As no size information are 4198c2ecf20Sopenharmony_ci * available in the incoming data, other IRQ might come. Every IRQ will trigger 4208c2ecf20Sopenharmony_ci * a read sequence with different length and will fill the current frame. 4218c2ecf20Sopenharmony_ci * The reception is complete once we reach a ST21NFCA_SOF_EOF. 4228c2ecf20Sopenharmony_ci */ 4238c2ecf20Sopenharmony_cistatic irqreturn_t st21nfca_hci_irq_thread_fn(int irq, void *phy_id) 4248c2ecf20Sopenharmony_ci{ 4258c2ecf20Sopenharmony_ci struct st21nfca_i2c_phy *phy = phy_id; 4268c2ecf20Sopenharmony_ci struct i2c_client *client; 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci int r; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci if (!phy || irq != phy->i2c_dev->irq) { 4318c2ecf20Sopenharmony_ci WARN_ON_ONCE(1); 4328c2ecf20Sopenharmony_ci return IRQ_NONE; 4338c2ecf20Sopenharmony_ci } 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci client = phy->i2c_dev; 4368c2ecf20Sopenharmony_ci dev_dbg(&client->dev, "IRQ\n"); 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci if (phy->hard_fault != 0) 4398c2ecf20Sopenharmony_ci return IRQ_HANDLED; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci r = st21nfca_hci_i2c_read(phy, phy->pending_skb); 4428c2ecf20Sopenharmony_ci if (r == -EREMOTEIO) { 4438c2ecf20Sopenharmony_ci phy->hard_fault = r; 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci nfc_hci_recv_frame(phy->hdev, NULL); 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci return IRQ_HANDLED; 4488c2ecf20Sopenharmony_ci } else if (r == -EAGAIN || r == -EIO) { 4498c2ecf20Sopenharmony_ci return IRQ_HANDLED; 4508c2ecf20Sopenharmony_ci } else if (r == -EBADMSG && phy->crc_trials < ARRAY_SIZE(wait_tab)) { 4518c2ecf20Sopenharmony_ci /* 4528c2ecf20Sopenharmony_ci * With ST21NFCA, only one interface (I2C, RF or SWP) 4538c2ecf20Sopenharmony_ci * may be active at a time. 4548c2ecf20Sopenharmony_ci * Having incorrect crc is usually due to i2c macrocell 4558c2ecf20Sopenharmony_ci * deactivation in the middle of a transmission. 4568c2ecf20Sopenharmony_ci * It may generate corrupted data on i2c. 4578c2ecf20Sopenharmony_ci * We give sometime to get i2c back. 4588c2ecf20Sopenharmony_ci * The complete frame will be repeated. 4598c2ecf20Sopenharmony_ci */ 4608c2ecf20Sopenharmony_ci msleep(wait_tab[phy->crc_trials]); 4618c2ecf20Sopenharmony_ci phy->crc_trials++; 4628c2ecf20Sopenharmony_ci phy->current_read_len = 0; 4638c2ecf20Sopenharmony_ci kfree_skb(phy->pending_skb); 4648c2ecf20Sopenharmony_ci } else if (r > 0) { 4658c2ecf20Sopenharmony_ci /* 4668c2ecf20Sopenharmony_ci * We succeeded to read data from the CLF and 4678c2ecf20Sopenharmony_ci * data is valid. 4688c2ecf20Sopenharmony_ci * Reset counter. 4698c2ecf20Sopenharmony_ci */ 4708c2ecf20Sopenharmony_ci nfc_hci_recv_frame(phy->hdev, phy->pending_skb); 4718c2ecf20Sopenharmony_ci phy->crc_trials = 0; 4728c2ecf20Sopenharmony_ci } else { 4738c2ecf20Sopenharmony_ci kfree_skb(phy->pending_skb); 4748c2ecf20Sopenharmony_ci } 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci phy->pending_skb = alloc_skb(ST21NFCA_HCI_LLC_MAX_SIZE * 2, GFP_KERNEL); 4778c2ecf20Sopenharmony_ci if (phy->pending_skb == NULL) { 4788c2ecf20Sopenharmony_ci phy->hard_fault = -ENOMEM; 4798c2ecf20Sopenharmony_ci nfc_hci_recv_frame(phy->hdev, NULL); 4808c2ecf20Sopenharmony_ci } 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci return IRQ_HANDLED; 4838c2ecf20Sopenharmony_ci} 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_cistatic struct nfc_phy_ops i2c_phy_ops = { 4868c2ecf20Sopenharmony_ci .write = st21nfca_hci_i2c_write, 4878c2ecf20Sopenharmony_ci .enable = st21nfca_hci_i2c_enable, 4888c2ecf20Sopenharmony_ci .disable = st21nfca_hci_i2c_disable, 4898c2ecf20Sopenharmony_ci}; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_cistatic const struct acpi_gpio_params enable_gpios = { 1, 0, false }; 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_cistatic const struct acpi_gpio_mapping acpi_st21nfca_gpios[] = { 4948c2ecf20Sopenharmony_ci { "enable-gpios", &enable_gpios, 1 }, 4958c2ecf20Sopenharmony_ci {}, 4968c2ecf20Sopenharmony_ci}; 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_cistatic int st21nfca_hci_i2c_probe(struct i2c_client *client, 4998c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 5008c2ecf20Sopenharmony_ci{ 5018c2ecf20Sopenharmony_ci struct device *dev = &client->dev; 5028c2ecf20Sopenharmony_ci struct st21nfca_i2c_phy *phy; 5038c2ecf20Sopenharmony_ci int r; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci dev_dbg(&client->dev, "%s\n", __func__); 5068c2ecf20Sopenharmony_ci dev_dbg(&client->dev, "IRQ: %d\n", client->irq); 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 5098c2ecf20Sopenharmony_ci nfc_err(&client->dev, "Need I2C_FUNC_I2C\n"); 5108c2ecf20Sopenharmony_ci return -ENODEV; 5118c2ecf20Sopenharmony_ci } 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci phy = devm_kzalloc(&client->dev, sizeof(struct st21nfca_i2c_phy), 5148c2ecf20Sopenharmony_ci GFP_KERNEL); 5158c2ecf20Sopenharmony_ci if (!phy) 5168c2ecf20Sopenharmony_ci return -ENOMEM; 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ci phy->i2c_dev = client; 5198c2ecf20Sopenharmony_ci phy->pending_skb = alloc_skb(ST21NFCA_HCI_LLC_MAX_SIZE * 2, GFP_KERNEL); 5208c2ecf20Sopenharmony_ci if (phy->pending_skb == NULL) 5218c2ecf20Sopenharmony_ci return -ENOMEM; 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci phy->current_read_len = 0; 5248c2ecf20Sopenharmony_ci phy->crc_trials = 0; 5258c2ecf20Sopenharmony_ci mutex_init(&phy->phy_lock); 5268c2ecf20Sopenharmony_ci i2c_set_clientdata(client, phy); 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci r = devm_acpi_dev_add_driver_gpios(dev, acpi_st21nfca_gpios); 5298c2ecf20Sopenharmony_ci if (r) 5308c2ecf20Sopenharmony_ci dev_dbg(dev, "Unable to add GPIO mapping table\n"); 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci /* Get EN GPIO from resource provider */ 5338c2ecf20Sopenharmony_ci phy->gpiod_ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 5348c2ecf20Sopenharmony_ci if (IS_ERR(phy->gpiod_ena)) { 5358c2ecf20Sopenharmony_ci nfc_err(dev, "Unable to get ENABLE GPIO\n"); 5368c2ecf20Sopenharmony_ci r = PTR_ERR(phy->gpiod_ena); 5378c2ecf20Sopenharmony_ci goto out_free; 5388c2ecf20Sopenharmony_ci } 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci phy->se_status.is_ese_present = 5418c2ecf20Sopenharmony_ci device_property_read_bool(&client->dev, "ese-present"); 5428c2ecf20Sopenharmony_ci phy->se_status.is_uicc_present = 5438c2ecf20Sopenharmony_ci device_property_read_bool(&client->dev, "uicc-present"); 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci r = st21nfca_hci_platform_init(phy); 5468c2ecf20Sopenharmony_ci if (r < 0) { 5478c2ecf20Sopenharmony_ci nfc_err(&client->dev, "Unable to reboot st21nfca\n"); 5488c2ecf20Sopenharmony_ci goto out_free; 5498c2ecf20Sopenharmony_ci } 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci r = devm_request_threaded_irq(&client->dev, client->irq, NULL, 5528c2ecf20Sopenharmony_ci st21nfca_hci_irq_thread_fn, 5538c2ecf20Sopenharmony_ci IRQF_ONESHOT, 5548c2ecf20Sopenharmony_ci ST21NFCA_HCI_DRIVER_NAME, phy); 5558c2ecf20Sopenharmony_ci if (r < 0) { 5568c2ecf20Sopenharmony_ci nfc_err(&client->dev, "Unable to register IRQ handler\n"); 5578c2ecf20Sopenharmony_ci goto out_free; 5588c2ecf20Sopenharmony_ci } 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci r = st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, 5618c2ecf20Sopenharmony_ci ST21NFCA_FRAME_HEADROOM, 5628c2ecf20Sopenharmony_ci ST21NFCA_FRAME_TAILROOM, 5638c2ecf20Sopenharmony_ci ST21NFCA_HCI_LLC_MAX_PAYLOAD, 5648c2ecf20Sopenharmony_ci &phy->hdev, 5658c2ecf20Sopenharmony_ci &phy->se_status); 5668c2ecf20Sopenharmony_ci if (r) 5678c2ecf20Sopenharmony_ci goto out_free; 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci return 0; 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ciout_free: 5728c2ecf20Sopenharmony_ci kfree_skb(phy->pending_skb); 5738c2ecf20Sopenharmony_ci return r; 5748c2ecf20Sopenharmony_ci} 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_cistatic int st21nfca_hci_i2c_remove(struct i2c_client *client) 5778c2ecf20Sopenharmony_ci{ 5788c2ecf20Sopenharmony_ci struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci dev_dbg(&client->dev, "%s\n", __func__); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci st21nfca_hci_remove(phy->hdev); 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci if (phy->powered) 5858c2ecf20Sopenharmony_ci st21nfca_hci_i2c_disable(phy); 5868c2ecf20Sopenharmony_ci if (phy->pending_skb) 5878c2ecf20Sopenharmony_ci kfree_skb(phy->pending_skb); 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci return 0; 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_cistatic const struct i2c_device_id st21nfca_hci_i2c_id_table[] = { 5938c2ecf20Sopenharmony_ci {ST21NFCA_HCI_DRIVER_NAME, 0}, 5948c2ecf20Sopenharmony_ci {} 5958c2ecf20Sopenharmony_ci}; 5968c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, st21nfca_hci_i2c_id_table); 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic const struct acpi_device_id st21nfca_hci_i2c_acpi_match[] = { 5998c2ecf20Sopenharmony_ci {"SMO2100", 0}, 6008c2ecf20Sopenharmony_ci {} 6018c2ecf20Sopenharmony_ci}; 6028c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, st21nfca_hci_i2c_acpi_match); 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_cistatic const struct of_device_id of_st21nfca_i2c_match[] = { 6058c2ecf20Sopenharmony_ci { .compatible = "st,st21nfca-i2c", }, 6068c2ecf20Sopenharmony_ci { .compatible = "st,st21nfca_i2c", }, 6078c2ecf20Sopenharmony_ci {} 6088c2ecf20Sopenharmony_ci}; 6098c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, of_st21nfca_i2c_match); 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistatic struct i2c_driver st21nfca_hci_i2c_driver = { 6128c2ecf20Sopenharmony_ci .driver = { 6138c2ecf20Sopenharmony_ci .name = ST21NFCA_HCI_I2C_DRIVER_NAME, 6148c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(of_st21nfca_i2c_match), 6158c2ecf20Sopenharmony_ci .acpi_match_table = ACPI_PTR(st21nfca_hci_i2c_acpi_match), 6168c2ecf20Sopenharmony_ci }, 6178c2ecf20Sopenharmony_ci .probe = st21nfca_hci_i2c_probe, 6188c2ecf20Sopenharmony_ci .id_table = st21nfca_hci_i2c_id_table, 6198c2ecf20Sopenharmony_ci .remove = st21nfca_hci_i2c_remove, 6208c2ecf20Sopenharmony_ci}; 6218c2ecf20Sopenharmony_cimodule_i2c_driver(st21nfca_hci_i2c_driver); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 6248c2ecf20Sopenharmony_ciMODULE_DESCRIPTION(DRIVER_DESC); 625