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