* [[linux-nfc] PATCH v1.0 0/3] Add support for ST95HF
@ 2015-09-12 7:21 Shikha Singh
2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 1/3] NFC: digital: Type4A tags support Shikha Singh
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Shikha Singh @ 2015-09-12 7:21 UTC (permalink / raw)
To: sameo, aloisio.almeida, lauro.venancio, linux-wireless, linux-nfc
Cc: raunaque.quaiser, manoj.kumar, sylvain.fidelis, patrick.sohn,
shikha.singh
Hello All,
This series of patch provide support of STMicroelectronics
NFC Transceiver "ST95HF".
This series include below 3 patches:
1. Modification in file of NFC digital layer to provide support of
ISO14443 Type4A tags.
2. Patch includes all ST95HF driver related files.
This release of driver supports ST95HF in initiator mode to support
read/write mode for IS014443 Type A and ISO14443 Type B tags.
3. Patch to provide binding doc of ST95HF to guide how to make node
entry of ST95HF in DT file.
To Do: ISO15693 tags read/write will be supported in upcoming release of driver.
This series of patch is based on Linux kernel 4.1.
Any feedbacks are most welcome.
Thanks & Regards,
Shikha
Shikha Singh (3):
NFC: digital: Type4A tags support
driver: nfc: st95hf: ST NFC Transceiver support
DT: bindings: net: nfc: ST95HF binding doc
.../devicetree/bindings/net/nfc/st95hf.txt | 55 +
drivers/nfc/Kconfig | 1 +
drivers/nfc/Makefile | 1 +
drivers/nfc/st95hf/Kconfig | 11 +
drivers/nfc/st95hf/Makefile | 6 +
drivers/nfc/st95hf/spi.c | 159 +++
drivers/nfc/st95hf/spi.h | 45 +
drivers/nfc/st95hf/st95hf.c | 1134 ++++++++++++++++++++
net/nfc/digital_core.c | 3 +-
9 files changed, 1414 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/net/nfc/st95hf.txt
create mode 100644 drivers/nfc/st95hf/Kconfig
create mode 100644 drivers/nfc/st95hf/Makefile
create mode 100644 drivers/nfc/st95hf/spi.c
create mode 100644 drivers/nfc/st95hf/spi.h
create mode 100644 drivers/nfc/st95hf/st95hf.c
--
1.8.2.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [[linux-nfc] PATCH v1.0 1/3] NFC: digital: Type4A tags support 2015-09-12 7:21 [[linux-nfc] PATCH v1.0 0/3] Add support for ST95HF Shikha Singh @ 2015-09-12 7:21 ` Shikha Singh 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support Shikha Singh 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 3/3] DT: bindings: net: nfc: ST95HF binding doc Shikha Singh 2 siblings, 0 replies; 7+ messages in thread From: Shikha Singh @ 2015-09-12 7:21 UTC (permalink / raw) To: sameo, aloisio.almeida, lauro.venancio, linux-wireless, linux-nfc Cc: raunaque.quaiser, manoj.kumar, sylvain.fidelis, patrick.sohn, shikha.singh The definition of DIGITAL_PROTO_NFCA_RF_TECH is modified to support ISO14443 Type4A tags. Without this change it is not possible to start polling for ISO14443 Type4A tags from the initiator side. Signed-off-by: Shikha Singh <shikha.singh@st.com> --- net/nfc/digital_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c index 009bcf3..7067970 100644 --- a/net/nfc/digital_core.c +++ b/net/nfc/digital_core.c @@ -20,7 +20,8 @@ #include "digital.h" #define DIGITAL_PROTO_NFCA_RF_TECH \ - (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK) + (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | \ + NFC_PROTO_NFC_DEP_MASK | NFC_PROTO_ISO14443_MASK) #define DIGITAL_PROTO_NFCB_RF_TECH NFC_PROTO_ISO14443_B_MASK -- 1.8.2.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support 2015-09-12 7:21 [[linux-nfc] PATCH v1.0 0/3] Add support for ST95HF Shikha Singh 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 1/3] NFC: digital: Type4A tags support Shikha Singh @ 2015-09-12 7:21 ` Shikha Singh 2015-10-22 6:24 ` Samuel Ortiz 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 3/3] DT: bindings: net: nfc: ST95HF binding doc Shikha Singh 2 siblings, 1 reply; 7+ messages in thread From: Shikha Singh @ 2015-09-12 7:21 UTC (permalink / raw) To: sameo, aloisio.almeida, lauro.venancio, linux-wireless, linux-nfc Cc: raunaque.quaiser, manoj.kumar, sylvain.fidelis, patrick.sohn, shikha.singh Release of linux driver for STMicroelectronics NFC Transceiver "ST95HF". This release of driver supports ST95HF in initiator role to read/write ISO14443 Type A and ISO14443 Type B tags. Signed-off-by: Shikha Singh <shikha.singh@st.com> --- drivers/nfc/Kconfig | 1 + drivers/nfc/Makefile | 1 + drivers/nfc/st95hf/Kconfig | 11 + drivers/nfc/st95hf/Makefile | 6 + drivers/nfc/st95hf/spi.c | 159 ++++++ drivers/nfc/st95hf/spi.h | 45 ++ drivers/nfc/st95hf/st95hf.c | 1134 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 1357 insertions(+) create mode 100644 drivers/nfc/st95hf/Kconfig create mode 100644 drivers/nfc/st95hf/Makefile create mode 100644 drivers/nfc/st95hf/spi.c create mode 100644 drivers/nfc/st95hf/spi.h create mode 100644 drivers/nfc/st95hf/st95hf.c diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 107714e..48e685b 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -74,4 +74,5 @@ source "drivers/nfc/nfcmrvl/Kconfig" source "drivers/nfc/st21nfca/Kconfig" source "drivers/nfc/st21nfcb/Kconfig" source "drivers/nfc/nxp-nci/Kconfig" +source "drivers/nfc/st95hf/Kconfig" endmenu diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index a4292d79..1505c95 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile @@ -14,5 +14,6 @@ obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/ obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb/ obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci/ +obj-$(CONFIG_NFC_ST95HF) += st95hf/ ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG diff --git a/drivers/nfc/st95hf/Kconfig b/drivers/nfc/st95hf/Kconfig new file mode 100644 index 0000000..745a2ce --- /dev/null +++ b/drivers/nfc/st95hf/Kconfig @@ -0,0 +1,11 @@ + +config NFC_ST95HF + tristate "ST95HF NFC Transceiver driver" + depends on SPI + help + This enables the ST NFC driver for ST95HF NFC transceiver. + This makes use of SPI framework to communicate with transceiver + and registered with NFC digital core to support Linux NFC framework. + + Say Y here to compile support for ST NFC transceiver linux driver + into the kernel or say M to compile it as module. diff --git a/drivers/nfc/st95hf/Makefile b/drivers/nfc/st95hf/Makefile new file mode 100644 index 0000000..2d8f8f3 --- /dev/null +++ b/drivers/nfc/st95hf/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for STMicroelectronics NFC transceiver ST95HF +# # + +obj-$(CONFIG_NFC_ST95HF) += st_transceiver.o +st_transceiver-objs := spi.o st95hf.o diff --git a/drivers/nfc/st95hf/spi.c b/drivers/nfc/st95hf/spi.c new file mode 100644 index 0000000..8e205e6 --- /dev/null +++ b/drivers/nfc/st95hf/spi.c @@ -0,0 +1,159 @@ + /* + * ---------------------------------------------------------------------------- + * drivers/nfc/st95hf/spi.c function definitions for SPI communication + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2015 STMicroelectronics – All Rights Reserved + * Author: Shikha Singh <shikha.singh@st.com> + * + * May be copied or modified under the terms of the GNU General Public + * License Version 2.0 only. See linux/COPYING for more information. + * --------------------------------------------------------------------------- + */ + +#include <linux/of_gpio.h> +#include "spi.h" + +/* Function to send user provided buffer to ST95HF through SPI */ +int spi_send_to_st95hf(struct spi_context *spicontext, + unsigned char *buffertx, int datalen, + enum req_type reqtype) +{ + struct spi_message m; + int result = 0; + struct spi_device *spidev = spicontext->spidev; + struct spi_transfer tx_transfer = { + .rx_buf = NULL, + .tx_buf = buffertx, + .len = datalen, + .cs_change = 0, + .bits_per_word = 0, + .delay_usecs = 0, + .speed_hz = 0, + }; + + spicontext->reply_from_st95 = 0; + + if (reqtype == SYNC) + spicontext->req_issync = true; + else + spicontext->req_issync = false; + + spi_message_init(&m); + spi_message_add_tail(&tx_transfer, &m); + + result = spi_sync(spidev, &m); + if (result) { + dev_err(&spidev->dev, + "error: sending cmd to st95hf using SPI\n"); + return result; + } + + if (reqtype == ASYNC) { /* return for asynchronous or no-wait case */ + return 0; + } + + do { + result = wait_event_interruptible_timeout( + spicontext->st95wait_queue, + spicontext->reply_from_st95 == 1, + 1000); + } while (result < 0); + + if (result == 0) { + dev_err(&spidev->dev, "error: response not ready timeout\n"); + return -ETIMEDOUT; + } + + if (result > 0) + result = 0; + + return result; +} +EXPORT_SYMBOL_GPL(spi_send_to_st95hf); + +/* Function to Receive command Response */ +int spi_receive_response(struct spi_context *spicontext, + unsigned char *receivebuff, + int *len) +{ + struct spi_transfer tx_takeresponse1; + struct spi_transfer tx_takeresponse2; + struct spi_transfer tx_takedata; + struct spi_message m; + unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE; + int ret = 0; + + struct spi_device *spidev = spicontext->spidev; + + *len = 0; + + memset(&tx_takeresponse1, 0x0, sizeof(struct spi_transfer)); + memset(&tx_takeresponse2, 0x0, sizeof(struct spi_transfer)); + memset(&tx_takedata, 0x0, sizeof(struct spi_transfer)); + + tx_takeresponse1.tx_buf = &readdata_cmd; + tx_takeresponse1.len = 1; + + tx_takeresponse2.rx_buf = receivebuff; + /* 1 byte Response code + 1 byte length of data */ + tx_takeresponse2.len = 2; + /* Dont allow to make chipselect high */ + tx_takeresponse2.cs_change = 1; + + spi_message_init(&m); + spi_message_add_tail(&tx_takeresponse1, &m); + spi_message_add_tail(&tx_takeresponse2, &m); + + ret = spi_sync(spidev, &m); + if (ret) + return ret; + + /* 2 bytes are already read */ + *len = 2; + + /*support of long frame*/ + if (receivebuff[0] & 0x60) + *len += (((receivebuff[0] & 0x60) >> 5) << 8) | receivebuff[1]; + else + *len += receivebuff[1]; + + /* Now make a transfer to take only relevant data */ + tx_takedata.rx_buf = &receivebuff[2]; + tx_takedata.len = (*len) - 2; + tx_takedata.cs_change = 0; + + spi_message_init(&m); + spi_message_add_tail(&tx_takedata, &m); + + return spi_sync(spidev, &m); +} +EXPORT_SYMBOL_GPL(spi_receive_response); + +int spi_receive_echo_response(struct spi_context *spicontext, + unsigned char *receivebuff) +{ + struct spi_transfer tx_takeresponse1; + struct spi_transfer tx_takedata; + struct spi_message m; + unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE; + struct spi_device *spidev = spicontext->spidev; + + memset(&tx_takeresponse1, 0x0, sizeof(struct spi_transfer)); + memset(&tx_takedata, 0x0, sizeof(struct spi_transfer)); + + tx_takeresponse1.tx_buf = &readdata_cmd; + tx_takeresponse1.len = 1; + tx_takeresponse1.rx_buf = NULL; + + tx_takedata.rx_buf = receivebuff; + tx_takedata.tx_buf = NULL; + tx_takedata.len = 1; + + spi_message_init(&m); + spi_message_add_tail(&tx_takeresponse1, &m); + spi_message_add_tail(&tx_takedata, &m); + + return spi_sync(spidev, &m); +} +EXPORT_SYMBOL_GPL(spi_receive_echo_response); diff --git a/drivers/nfc/st95hf/spi.h b/drivers/nfc/st95hf/spi.h new file mode 100644 index 0000000..aa3eea0d --- /dev/null +++ b/drivers/nfc/st95hf/spi.h @@ -0,0 +1,45 @@ + /* + * ----------------------------------------------------------------------------- + * drivers/nfc/st95hf/spi.h functions declarations for SPI communication + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2015 STMicroelectronics – All Rights Reserved + * Author: Shikha Singh <shikha.singh@st.com> + * + * May be copied or modified under the terms of the GNU General Public + * License Version 2.0 only. See linux/COPYING for more information. + * --------------------------------------------------------------------------- + */ + +#ifndef __LINUX_ST95HF_SPI_H +#define __LINUX_ST95HF_SPI_H + +#include <linux/spi/spi.h> + +struct spi_context { + int reply_from_st95; + wait_queue_head_t st95wait_queue; + bool req_issync; + struct spi_device *spidev; +}; + +/* Flags to differentiate synchronous & asynchronous request */ +enum req_type { + SYNC, + ASYNC, +}; + +#define ST95HF_COMMAND_RECEIVE 0x02 + +int spi_send_to_st95hf(struct spi_context *spicontext, + unsigned char *buffertx, int datalen, + enum req_type reqtype); + +int spi_receive_response(struct spi_context *spicontext, + unsigned char *receivebuff, + int *len); + +int spi_receive_echo_response(struct spi_context *spicontext, + unsigned char *receivebuff); + +#endif diff --git a/drivers/nfc/st95hf/st95hf.c b/drivers/nfc/st95hf/st95hf.c new file mode 100644 index 0000000..1fa3cd5 --- /dev/null +++ b/drivers/nfc/st95hf/st95hf.c @@ -0,0 +1,1134 @@ +/* + * ---------------------------------------------------------------------------- + * Driver for STNFC Transceiver (Role: 14443_A/B Tag Reader/Writer) + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2015 STMicroelectronics All Rights Reserved + * Author: Shikha Singh <shikha.singh@st.com> + * + * May be copied or modified under the terms of the GNU General Public + * License Version 2.0 only. See linux/COPYING for more information. + * --------------------------------------------------------------------------- + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/err.h> +#include <linux/nfc.h> +#include <linux/gpio.h> +#include <linux/of_gpio.h> +#include <linux/of_irq.h> +#include <linux/netdevice.h> +#include <linux/wait.h> +#include <net/nfc/digital.h> +#include <net/nfc/nfc.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include "spi.h" + +#define VERSION "0.1" + +/* Command Send Interface */ +/* Basic ST95HF SPI CMD Ids */ +#define ST95HF_COMMAND_SEND 0x0 +#define ST95HF_COMMAND_RESET 0x1 + +/* ST95HF_COMMAND_SEND CMD Ids */ +#define ECHO_CMD 0x55 +#define WRITE_REGISTER_CMD 0x9 +#define PROTOCOL_SELECT_CMD 0x2 +#define SEND_RECEIVE_CMD 0x4 + +/* High level cmd interface */ +#define MAX_CMD_PARAMS 4 +#define ISO14443A_PROTOCOL_CODE 0x2 +#define ISO14443B_PROTOCOL_CODE 0x3 + +enum st95hf_cmd_list { + ECHO, + ISO14443A_CONFIG, + ISO14443A_DEMOGAIN, + ISO14443B_DEMOGAIN, + ISO14443A_PROTOCOL_SELECT, + ISO14443B_PROTOCOL_SELECT, + RESET, + WTX_RESPONSE, + FIELD_OFF, +}; + +struct cmd { + int cmd_len; + unsigned char cmd_id; + unsigned char no_cmd_params; + unsigned char cmd_params[MAX_CMD_PARAMS]; + enum req_type req; +}; + +struct param_list { + int param_offset; + int new_param_val; +}; + +static const struct cmd cmd_array[] = { + { + .cmd_len = 0x2, + .cmd_id = ECHO_CMD, + .no_cmd_params = 0, + .req = SYNC, + }, + { + .cmd_len = 0x7, + .cmd_id = WRITE_REGISTER_CMD, + .no_cmd_params = 0x4, + .cmd_params = {0x3A, 0x00, 0x5A, 0x04}, + .req = SYNC, + }, + { + .cmd_len = 0x7, + .cmd_id = WRITE_REGISTER_CMD, + .no_cmd_params = 0x4, + .cmd_params = {0x68, 0x01, 0x01, 0xDF}, + .req = SYNC, + }, + { + .cmd_len = 0x7, + .cmd_id = WRITE_REGISTER_CMD, + .no_cmd_params = 0x4, + .cmd_params = {0x68, 0x01, 0x01, 0x51}, + .req = SYNC, + }, + { + .cmd_len = 0x7, + .cmd_id = PROTOCOL_SELECT_CMD, + .no_cmd_params = 0x4, + .cmd_params = {ISO14443A_PROTOCOL_CODE, 0x00, 0x01, 0xA0}, + .req = SYNC, + }, + { + .cmd_len = 0x7, + .cmd_id = PROTOCOL_SELECT_CMD, + .no_cmd_params = 0x4, + .cmd_params = {ISO14443B_PROTOCOL_CODE, 0x01, 0x03, 0xFF}, + .req = SYNC, + }, + { + .cmd_len = 0x1, + .cmd_id = ST95HF_COMMAND_RESET, + .no_cmd_params = 0x0, + .req = ASYNC, + }, + { + .cmd_len = 0x6, + .cmd_id = SEND_RECEIVE_CMD, + .no_cmd_params = 0x3, + .cmd_params = {0xF2, 0x00, 0x28}, + .req = ASYNC, + }, + { + .cmd_len = 0x5, + .cmd_id = PROTOCOL_SELECT_CMD, + .no_cmd_params = 0x2, + .cmd_params = {0x0, 0x0}, + .req = SYNC, + }, +}; + +#define MAX_CMD_LEN 0x7 + +/* + * head room len is 3 + * 1 byte for control byte + * 1 byte for cmd + * 1 byte for size + */ +#define ST95HF_HEADROOM_LEN 3 + +/* + * tailroom is 1 for ISO14443A + * and 0 for ISO14443B, hence the + * max value 1 should be taken + */ +#define ST95HF_TAILROOM_LEN 1 + +/* Command Response interface */ +#define SELECT_PROTOCOL_RES_LEN 2 +#define MAX_RESPONSE_BUFFER_SIZE 280 +#define ECHORESPONSE 0x55 +#define WTX_REQ_FROM_TAG 0xF2 + +/* ST95HF Driver defs */ +/* supported protocols */ +#define ST95HF_SUPPORTED_PROT (NFC_PROTO_ISO14443_MASK | \ + NFC_PROTO_ISO14443_B_MASK) + +/* driver capabilities */ +#define ST95HF_CAPABILITIES NFC_DIGITAL_DRV_CAPS_IN_CRC + +/* Misc defs */ +#define HIGH 1 +#define LOW 0 +#define ISO14443A_RATS_REQ 0xE0 + +struct st95_digital_cmd_complete_arg { + struct sk_buff *skb_resp; + nfc_digital_cmd_complete_t complete_cb; + void *cb_usrarg; + bool rats; +}; + +/* Below structure contains driver specific data */ +struct st95hf_context { + struct spi_context spicontext; + struct nfc_digital_dev *ddev; + struct nfc_dev *nfcdev; + unsigned int st95hf_enable_gpio; + struct st95_digital_cmd_complete_arg *complete_cb_arg; + struct regulator *st95hf_supply; + unsigned char sendrcv_lastbyte; + u8 current_protocol; + u8 current_rf_tech; + int fwi; +}; + +/* Below helper functions to send command to ST95HF */ +static int st95hf_send_cmd(struct st95hf_context *stcontext, + enum st95hf_cmd_list cmd, + int no_modif, + struct param_list *list_array) +{ + unsigned char spi_cmd_buffer[MAX_CMD_LEN]; + int i; + + if (cmd_array[cmd].cmd_len > MAX_CMD_LEN) + return -EINVAL; + if (cmd_array[cmd].no_cmd_params < no_modif) + return -EINVAL; + if (no_modif && !list_array) + return -EINVAL; + + spi_cmd_buffer[0] = ST95HF_COMMAND_SEND; + spi_cmd_buffer[1] = cmd_array[cmd].cmd_id; + spi_cmd_buffer[2] = cmd_array[cmd].no_cmd_params; + + memcpy(&spi_cmd_buffer[3], cmd_array[cmd].cmd_params, + spi_cmd_buffer[2]); + + for (i = 0; i < no_modif; i++) { + if (list_array[i].param_offset >= cmd_array[cmd].no_cmd_params) + return -EINVAL; + spi_cmd_buffer[3 + list_array[i].param_offset] = + list_array[i].new_param_val; + } + + return spi_send_to_st95hf(&stcontext->spicontext, + spi_cmd_buffer, + cmd_array[cmd].cmd_len, + cmd_array[cmd].req); +} + +/* + * Below helper function to receive response from ST95HF when + * length of response is 2 bytes and 1st byte == 0x0 indicate success + */ +static int spi_receive_generic(struct st95hf_context *st95context) +{ + int result; + unsigned char st95hf_response_arr[2]; + int response_length; + struct device *dev = &st95context->spicontext.spidev->dev; + + result = spi_receive_response(&st95context->spicontext, + st95hf_response_arr, + &response_length); + + if (result) { + dev_err(dev, "spi error spi_receive_generic(), err = 0x%x\n", + result); + return result; + } + + if (st95hf_response_arr[0]) { + dev_err(dev, "st95hf error spi_receive_generic(), err = 0x%x\n", + st95hf_response_arr[0]); + return -EIO; + } + + return 0; +} + +static int st95hf_echo_command(struct st95hf_context *st95context) +{ + int result = 0; + unsigned char echo_response; + + result = st95hf_send_cmd(st95context, ECHO, 0, NULL); + if (result) + return result; + + /* If control reached here, response can be taken */ + result = spi_receive_echo_response(&st95context->spicontext, + &echo_response); + if (result) { + dev_err(&st95context->spicontext.spidev->dev, "err: echo response receieve error\n"); + return result; + } + + if (echo_response == ECHORESPONSE) + return 0; + + return -EIO; +} + +static int st95hf_select_protocol(struct st95hf_context *stcontext, int type) +{ + int result = 0; + struct device *dev; + + dev = &stcontext->nfcdev->dev; + + switch (type) { + case NFC_DIGITAL_RF_TECH_106A: + stcontext->current_rf_tech = NFC_DIGITAL_RF_TECH_106A; + result = st95hf_send_cmd(stcontext, + ISO14443A_PROTOCOL_SELECT, + 0, + NULL); + if (result) { + dev_err(dev, "protocol sel send, err = 0x%x\n", + result); + return result; + } + break; + case NFC_DIGITAL_RF_TECH_106B: + stcontext->current_rf_tech = NFC_DIGITAL_RF_TECH_106B; + result = st95hf_send_cmd(stcontext, + ISO14443B_PROTOCOL_SELECT, + 0, + NULL); + if (result) { + dev_err(dev, "protocol sel send, err = 0x%x\n", + result); + return result; + } + break; + default: + /* This release supports only 14443 TypeA and TypeB */ + return -EINVAL; + } + + result = spi_receive_generic(stcontext); + if (result) { + dev_err(dev, "protocol sel response, err = 0x%x\n", result); + return result; + } + /* Check if 14443A/B then do some additional settings */ + if (type == NFC_DIGITAL_RF_TECH_106A) { + /* 14443A config setting */ + result = st95hf_send_cmd(stcontext, ISO14443A_CONFIG, 0, NULL); + if (result) { + dev_err(dev, "config cmd send, err = 0x%x\n", result); + return result; + } + + result = spi_receive_generic(stcontext); + if (result) { + dev_err(dev, "config cmd response, err = 0x%x\n", + result); + return result; + } + + /* Demo gain setting for type 4a */ + result = st95hf_send_cmd(stcontext, + ISO14443A_DEMOGAIN, + 0, + NULL); + if (result) { + dev_err(dev, "demogain cmd send, err = 0x%x\n", result); + return result; + } + + result = spi_receive_generic(stcontext); + if (result) { + dev_err(dev, "demogain cmd response, err = 0x%x\n", + result); + return result; + } + } + + if (type == NFC_DIGITAL_RF_TECH_106B) { + /* + * some delay is required after select protocol + * command in case of ISO14443 Type B + */ + usleep_range(50000, 60000); + + result = st95hf_send_cmd(stcontext, + ISO14443B_DEMOGAIN, + 0, + NULL); + if (result) { + dev_err(dev, "type b demogain cmd send, err = 0x%x\n", + result); + return result; + } + + result = spi_receive_generic(stcontext); + if (result) { + dev_err(dev, "type b demogain cmd response, err = 0x%x\n", + result); + return result; + } + } + + return 0; +} + +static void st95hf_send_st95enable_negativepulse(struct st95hf_context *st95con) +{ + /* First make irq_in pin high */ + gpio_set_value(st95con->st95hf_enable_gpio, HIGH); + + /* wait for 1 milisecond */ + usleep_range(1000, 2000); + + /* Make irq_in pin low */ + gpio_set_value(st95con->st95hf_enable_gpio, LOW); + + /* wait for minimum interrupt pulse to make st95 active */ + usleep_range(1000, 2000); /* wait for 1 milisecond */ + + /* At end make it high */ + gpio_set_value(st95con->st95hf_enable_gpio, HIGH); +} + +/* + * Send a reset sequence over SPI bus (Reset command + wait 3ms + + * negative pulse on st95hf enable gpio + */ +static int st95hf_send_spi_reset_sequence(struct st95hf_context *st95context) +{ + int result = 0; + + result = st95hf_send_cmd(st95context, RESET, 0, NULL); + if (result) { + dev_err(&st95context->spicontext.spidev->dev, + "spi reset sequence cmd error = %d", result); + return result; + } + + /* wait for 3 milisecond to complete the controller reset process */ + usleep_range(3000, 4000); + + /* send negative pulse to make st95hf active */ + st95hf_send_st95enable_negativepulse(st95context); + + /* wait for 10 milisecond : HFO setup time */ + usleep_range(10000, 20000); + + return result; +} + +static int st95hf_por_sequence(struct st95hf_context *st95context) +{ + int nth_attempt = 1; + int result; + + st95hf_send_st95enable_negativepulse(st95context); + + usleep_range(5000, 6000); + do { + /* send an ECHO command and checks ST95HF response */ + result = st95hf_echo_command(st95context); + + dev_dbg(&st95context->spicontext.spidev->dev, + "response from echo function = 0x%x, attempt = %d\n", + result, nth_attempt); + + if (!result) + return 0; + + /* send an pulse on IRQ in case of the chip is on sleep state */ + if (nth_attempt == 2) + st95hf_send_st95enable_negativepulse(st95context); + else + st95hf_send_spi_reset_sequence(st95context); + + /* delay of 50 milisecond */ + usleep_range(50000, 51000); + } while (nth_attempt++ < 3); + + return -ETIMEDOUT; +} + +static int iso14443_config_fdt(struct st95hf_context *st95context, int wtxm) +{ + int result = 0; + struct device *dev = &st95context->spicontext.spidev->dev; + struct nfc_digital_dev *nfcddev = st95context->ddev; + unsigned char pp_typeb; + struct param_list new_params[2]; + + pp_typeb = cmd_array[ISO14443B_PROTOCOL_SELECT].cmd_params[2]; + + if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) { + if (st95context->fwi < 4) + st95context->fwi = 4; + } + + new_params[0].param_offset = 2; + if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) + new_params[0].new_param_val = st95context->fwi; + else if (nfcddev->curr_protocol == NFC_PROTO_ISO14443_B) + new_params[0].new_param_val = pp_typeb; + + new_params[1].param_offset = 3; + new_params[1].new_param_val = wtxm; + + if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) + result = st95hf_send_cmd(st95context, + ISO14443A_PROTOCOL_SELECT, + 2, + new_params); + else if (nfcddev->curr_protocol == NFC_PROTO_ISO14443_B) + result = st95hf_send_cmd(st95context, + ISO14443B_PROTOCOL_SELECT, + 2, + new_params); + if (result) { + dev_err(dev, "WTX select protocol cmd send, err = 0x%x\n", + result); + return result; + } + + result = spi_receive_generic(st95context); + if (result) { + dev_err(dev, "WTX select protocol response, err = 0x%x\n", + result); + return result; + } + + if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) { + result = st95hf_send_cmd(st95context, + ISO14443A_CONFIG, + 0, + NULL); + if (result) { + dev_err(dev, "WTX config cmd send, err = 0x%x\n", + result); + return result; + } + result = spi_receive_generic(st95context); + if (result) { + dev_err(dev, "WTX config cmd response, err = 0x%x\n", + result); + return result; + } + } + + if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) + result = st95hf_send_cmd(st95context, + ISO14443A_DEMOGAIN, + 0, + NULL); + else if (nfcddev->curr_protocol == NFC_PROTO_ISO14443_B) + result = st95hf_send_cmd(st95context, + ISO14443B_DEMOGAIN, + 0, + NULL); + if (result) { + dev_err(dev, "WTX demogain cmd send, err = 0x%x\n", result); + return result; + } + + result = spi_receive_generic(st95context); + if (result) { + dev_err(dev, "WTX demogain cmd response, err = 0x%x\n", result); + return result; + } + + return 0; +} + +static irqreturn_t irq_handler(int irq, void *st95hfcontext) +{ + struct st95hf_context *stcontext = + (struct st95hf_context *)st95hfcontext; + + if (stcontext->spicontext.req_issync) { + stcontext->spicontext.reply_from_st95 = 1; + wake_up_interruptible(&stcontext->spicontext.st95wait_queue); + return IRQ_HANDLED; + } + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t irq_thread_handler(int irq, void *st95hfcontext) +{ + int result; + int res_len; + int skb_len; + static bool wtx; + struct param_list new_params[1]; + struct st95hf_context *stcontext = + (struct st95hf_context *)st95hfcontext; + unsigned char error_byte; + struct device *dev = &stcontext->nfcdev->dev; + struct nfc_digital_dev *nfcddev = stcontext->ddev; + unsigned char val_mm; + + struct st95_digital_cmd_complete_arg *cb_arg = + stcontext->complete_cb_arg; + + if (!cb_arg) { + dev_err(dev, "cb_arg is NULL in threaded ISR\n"); + BUG(); + } + + result = spi_receive_response(&stcontext->spicontext, + cb_arg->skb_resp->data, + &res_len); + if (result) { + dev_err(dev, "res receive threaded ISR err = 0x%x\n", result); + goto end; + } + + if (*((cb_arg->skb_resp->data) + 2) == WTX_REQ_FROM_TAG) { + /* Request for new FWT from tag */ + result = iso14443_config_fdt(stcontext, + (*((cb_arg->skb_resp->data) + 3) + & 0x3f)); + if (result) { + dev_err(dev, "Config. setting error on WTX req, err = 0x%x\n", + result); + goto end; + } + wtx = true; + + /* ASYNC req as no response expected */ + new_params[0].param_offset = 1; + new_params[0].new_param_val = + *((cb_arg->skb_resp->data) + 3); + + result = st95hf_send_cmd(stcontext, + WTX_RESPONSE, + 1, + new_params); + if (result) { + dev_err(dev, "WTX response send, err = 0x%x\n", result); + goto end; + } + return IRQ_HANDLED; + } + + /* First check ST95HF specific error */ + if ((*cb_arg->skb_resp->data) & 0xf) { + dev_err(dev, "st95hf, err code = 0x%x, len of data received = %d\n", + *cb_arg->skb_resp->data, + *(cb_arg->skb_resp->data + 1)); + + result = -EIO; + goto end; + } + + /* Check for CRC err only if CRC is present in the tag response */ + switch (stcontext->current_rf_tech) { + case NFC_DIGITAL_RF_TECH_106A: + if (stcontext->sendrcv_lastbyte == 0x28) { + error_byte = *(cb_arg->skb_resp->data + res_len - 3); + if (error_byte & 0x20) { + /* CRC error occurred */ + dev_err(dev, "CRC byte rec frame = 0x%x\n", + error_byte); + result = -EIO; + goto end; + } + } + break; + case NFC_DIGITAL_RF_TECH_106B: + error_byte = *(cb_arg->skb_resp->data + res_len - 1); + if (error_byte & 0x01) { + /* CRC error occurred */ + dev_err(dev, "CRC byte rec frame = 0x%x\n", error_byte); + result = -EIO; + goto end; + } + break; + } + + /* Process the response */ + skb_put(cb_arg->skb_resp, res_len); + /* Remove st95 header */ + skb_pull(cb_arg->skb_resp, 2); + + skb_len = cb_arg->skb_resp->len; + + /* check if it is case of RATS request reply & FWI is present */ + if (nfcddev->curr_protocol == NFC_PROTO_ISO14443 && cb_arg->rats) { + /* if FWI is present, check format byte */ + if ((*(cb_arg->skb_resp->data + 1) & 0x20) == 0x20) { + if ((*(cb_arg->skb_resp->data + 1) & 0x10) == 0x10) + stcontext->fwi = + (*(cb_arg->skb_resp->data + 3) & 0xF0) + >> 4; + else + stcontext->fwi = + (*(cb_arg->skb_resp->data + 2) & 0xF0) + >> 4; + } + + val_mm = cmd_array[ISO14443A_PROTOCOL_SELECT].cmd_params[3]; + + result = iso14443_config_fdt(stcontext, val_mm); + if (result) { + dev_err(dev, "error in config_fdt to handle fwi of ATS, error=%d\n", + result); + goto end; + } + } + + /* Remove CRC bytes only if received frames data has an eod (CRC) */ + switch (stcontext->current_rf_tech) { + case NFC_DIGITAL_RF_TECH_106A: + if (stcontext->sendrcv_lastbyte == 0x28) + skb_trim(cb_arg->skb_resp, (skb_len - 5)); + else + skb_trim(cb_arg->skb_resp, (skb_len - 3)); + break; + case NFC_DIGITAL_RF_TECH_106B: + skb_trim(cb_arg->skb_resp, (skb_len - 3)); + break; + } + + /* + * If select protocol is done on wtx req. do select protocol + * again with default values + */ + if (wtx) { + wtx = false; + if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) { + val_mm = cmd_array[ISO14443A_PROTOCOL_SELECT]. + cmd_params[3]; + result = iso14443_config_fdt(stcontext, val_mm); + } else if (nfcddev->curr_protocol == + NFC_PROTO_ISO14443_B) { + val_mm = cmd_array[ISO14443B_PROTOCOL_SELECT]. + cmd_params[3]; + result = iso14443_config_fdt(stcontext, val_mm); + } + if (result) { + dev_err(dev, "Default config. setting error after WTX processing, err = 0x%x\n", + result); + goto end; + } + } + + /* Call of provided callback */ + cb_arg->complete_cb(stcontext->ddev, + cb_arg->cb_usrarg, + cb_arg->skb_resp); + + kfree(cb_arg); + stcontext->complete_cb_arg = NULL; + + return IRQ_HANDLED; + +end: + kfree_skb(cb_arg->skb_resp); + cb_arg->skb_resp = ERR_PTR(result); + cb_arg->complete_cb(stcontext->ddev, + cb_arg->cb_usrarg, + cb_arg->skb_resp); + kfree(cb_arg); + stcontext->complete_cb_arg = NULL; + wtx = false; + + return IRQ_HANDLED; +} + +/* NFC ops functions definition */ +int st95hf_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param) +{ + struct st95hf_context *stcontext = nfc_digital_get_drvdata(ddev); + + if (type == NFC_DIGITAL_CONFIG_RF_TECH) + return st95hf_select_protocol(stcontext, param); + + if (type == NFC_DIGITAL_CONFIG_FRAMING) { + switch (param) { + case NFC_DIGITAL_FRAMING_NFCA_SHORT: + stcontext->sendrcv_lastbyte = 0x07; + break; + case NFC_DIGITAL_FRAMING_NFCA_STANDARD: + stcontext->sendrcv_lastbyte = 0x08; + break; + case NFC_DIGITAL_FRAMING_NFCA_T4T: + case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP: + case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A: + stcontext->sendrcv_lastbyte = 0x28; + break; + case NFC_DIGITAL_FRAMING_NFCB: + break; + } + } + + return 0; +} + +static int rf_off(struct st95hf_context *stcontext) +{ + int rc; + struct device *dev; + + dev = &stcontext->nfcdev->dev; + + rc = st95hf_send_cmd(stcontext, FIELD_OFF, 0, NULL); + if (rc) { + dev_err(dev, "protocol sel send fielf off, err = 0x%x\n", + rc); + return rc; + } + + rc = spi_receive_generic(stcontext); + if (rc) { + dev_err(dev, "protocol sel response, err = 0x%x\n", rc); + return rc; + } + + return 0; +} + +int st95hf_in_send_cmd(struct nfc_digital_dev *ddev, + struct sk_buff *skb, + u16 timeout, + nfc_digital_cmd_complete_t cb, + void *arg) +{ + struct st95hf_context *stcontext = nfc_digital_get_drvdata(ddev); + int rc; + struct sk_buff *skb_resp; + struct st95_digital_cmd_complete_arg *cb_arg; + int len_data_to_tag = 0; + unsigned char *temp; + + skb_resp = alloc_skb(MAX_RESPONSE_BUFFER_SIZE, GFP_KERNEL); + if (!skb_resp) { + rc = -ENOMEM; + goto error; + } + + switch (stcontext->current_rf_tech) { + case NFC_DIGITAL_RF_TECH_106A: + len_data_to_tag = skb->len + 1; + temp = skb_put(skb, 1); + *(temp) = stcontext->sendrcv_lastbyte; + break; + case NFC_DIGITAL_RF_TECH_106B: + len_data_to_tag = skb->len; + break; + default: + rc = -EINVAL; + goto free_skb_resp; + } + + skb_push(skb, 3); + *((unsigned char *)(skb->data)) = ST95HF_COMMAND_SEND; + *((unsigned char *)(skb->data) + 1) = SEND_RECEIVE_CMD; + *((unsigned char *)(skb->data) + 2) = len_data_to_tag; + + cb_arg = kzalloc(sizeof(*cb_arg), GFP_KERNEL); + if (!cb_arg) { + rc = -ENOMEM; + goto free_skb_resp; + } + + cb_arg->skb_resp = skb_resp; + cb_arg->cb_usrarg = arg; + cb_arg->complete_cb = cb; + if ((*((skb->data) + 3) == ISO14443A_RATS_REQ) && + ddev->curr_protocol == NFC_PROTO_ISO14443) + cb_arg->rats = true; + + /* save received arg in st95hf context */ + stcontext->complete_cb_arg = cb_arg; + + rc = spi_send_to_st95hf(&stcontext->spicontext, skb->data, + skb->len, + ASYNC); + if (rc) { + nfc_err(&stcontext->nfcdev->dev, + "Error %d trying to perform data_exchange", rc); + goto free_arg; + } + + kfree_skb(skb); + return rc; + +free_arg: + kfree(cb_arg); + stcontext->complete_cb_arg = NULL; +free_skb_resp: + kfree_skb(skb_resp); +error: + kfree_skb(skb); + + return rc; +} + +/* p2p will be supported in a later release ! */ +int st95hf_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param) +{ + return 0; +} + +int st95hf_tg_send_cmd(struct nfc_digital_dev *ddev, + struct sk_buff *skb, + u16 timeout, + nfc_digital_cmd_complete_t cb, + void *arg) +{ + return 0; +} + +int st95hf_tg_listen(struct nfc_digital_dev *ddev, + u16 timeout, + nfc_digital_cmd_complete_t cb, + void *arg) +{ + return 0; +} + +int st95hf_tg_get_rf_tech(struct nfc_digital_dev *ddev, u8 *rf_tech) +{ + return 0; +} + +int st95hf_switch_rf(struct nfc_digital_dev *ddev, bool on) +{ + u8 rf_tech; + struct st95hf_context *stcontext = nfc_digital_get_drvdata(ddev); + + rf_tech = ddev->curr_rf_tech; + + if (on) + /* switch on RF field */ + return st95hf_select_protocol(stcontext, rf_tech); + + /* switch OFF RF field */ + return rf_off(stcontext); +} + +/* TODO st95hf_abort_cmd */ +void st95hf_abort_cmd(struct nfc_digital_dev *ddev) +{ +} + +static struct nfc_digital_ops st95hf_nfc_digital_ops = { + .in_configure_hw = st95hf_in_configure_hw, + .in_send_cmd = st95hf_in_send_cmd, + + .tg_listen = st95hf_tg_listen, + .tg_configure_hw = st95hf_tg_configure_hw, + .tg_send_cmd = st95hf_tg_send_cmd, + .tg_get_rf_tech = st95hf_tg_get_rf_tech, + + .switch_rf = st95hf_switch_rf, + .abort_cmd = st95hf_abort_cmd, +}; + +static const struct spi_device_id st95hf_id[] = { + { "st95hf", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, st95hf_id); + +void tag_deactivation(struct nfc_dev *nfcdev) +{ + struct nfc_digital_dev *digitaldev; + + digitaldev = (struct nfc_digital_dev *)dev_get_drvdata(&nfcdev->dev); + + nfcdev->active_target = NULL; + + digitaldev->curr_protocol = 0x0; +} + +static int st95hf_probe(struct spi_device *nfc_spi_dev) +{ + int ret; + + struct st95hf_context *st95context; + struct spi_context *spicontext; + struct device_node *np = nfc_spi_dev->dev.of_node; + + pr_info("ST SPI SLAVE DRIVER (ST95HF R/W 14443A/B) PROBE CALLED\n"); + + st95context = devm_kzalloc(&nfc_spi_dev->dev, + sizeof(struct st95hf_context), + GFP_KERNEL); + if (!st95context) + return -ENOMEM; + + spicontext = &st95context->spicontext; + + spicontext->spidev = nfc_spi_dev; + + st95context->fwi = cmd_array[ISO14443A_PROTOCOL_SELECT].cmd_params[2]; + + if (of_get_property(np, "st95hfvin-supply", NULL)) { + st95context->st95hf_supply = + devm_regulator_get(&nfc_spi_dev->dev, "st95hfvin"); + if (IS_ERR(st95context->st95hf_supply)) { + dev_err(&nfc_spi_dev->dev, "failed to acquire regulator\n"); + return PTR_ERR(st95context->st95hf_supply); + } + + ret = regulator_enable(st95context->st95hf_supply); + if (ret) { + dev_err(&nfc_spi_dev->dev, "failed to enable regulator\n"); + return ret; + } + } + + init_waitqueue_head(&spicontext->st95wait_queue); + + /* + * Store spicontext in spi device object for using it in + * remove & resume function + */ + dev_set_drvdata(&nfc_spi_dev->dev, spicontext); + + st95context->st95hf_enable_gpio = + of_get_named_gpio(nfc_spi_dev->dev.of_node, + "st,st95hf-enable-gpio", + 0); + if (st95context->st95hf_enable_gpio < 0) { + ret = st95context->st95hf_enable_gpio; + goto regulator_clean; + } + + ret = gpio_request(st95context->st95hf_enable_gpio, + "st95hf_enable_gpio"); + if (ret) + goto regulator_clean; + + ret = gpio_direction_output(st95context->st95hf_enable_gpio, 1); + if (ret) + goto free_enable_gpio; + + if (nfc_spi_dev->irq > 0) { + if (devm_request_threaded_irq(&nfc_spi_dev->dev, + nfc_spi_dev->irq, + irq_handler, + irq_thread_handler, + IRQF_SHARED, + "st95hf", + (void *)st95context) < 0) { + dev_err(&nfc_spi_dev->dev, "err: irq request for st95hf is failed\n"); + ret = -ENODEV; + goto free_enable_gpio; + } + } + + /* + * Send negative pulse to make st95hf active if last reset occur + * while in Tag detection low power state + */ + st95hf_send_st95enable_negativepulse(st95context); + + /* + * First reset SPI to handle hot reset and recurrent make run command + * It will put the device in Power ON state which make the state of + * device identical to state at the time of cold reset + */ + ret = st95hf_send_spi_reset_sequence(st95context); + if (ret) { + dev_err(&nfc_spi_dev->dev, "err: spi_reset_sequence failed\n"); + goto free_enable_gpio; + } + + /* call PowerOnReset sequence of ST95hf to activate it */ + ret = st95hf_por_sequence(st95context); + if (ret) { + dev_err(&nfc_spi_dev->dev, "err: por seq failed for st95hf\n"); + goto free_enable_gpio; + } + + /* Create NFC dev object and register with NFC Subsystem */ + st95context->ddev = nfc_digital_allocate_device(&st95hf_nfc_digital_ops, + ST95HF_SUPPORTED_PROT, + ST95HF_CAPABILITIES, + ST95HF_HEADROOM_LEN, + ST95HF_TAILROOM_LEN); + if (!st95context->ddev) { + ret = -ENOMEM; + goto free_enable_gpio; + } + + st95context->nfcdev = st95context->ddev->nfc_dev; + + ret = nfc_digital_register_device(st95context->ddev); + if (ret) { + nfc_digital_free_device(st95context->ddev); + goto free_enable_gpio; + } + + /* store st95context in nfc device object */ + nfc_digital_set_drvdata(st95context->ddev, st95context); + + return ret; + +free_enable_gpio: + gpio_free(st95context->st95hf_enable_gpio); +regulator_clean: + if (st95context->st95hf_supply) + regulator_disable(st95context->st95hf_supply); + return ret; +} + +static int st95hf_remove(struct spi_device *nfc_spi_dev) +{ + struct spi_context *spictx = dev_get_drvdata(&nfc_spi_dev->dev); + + struct st95hf_context *stcontext = container_of(spictx, + struct st95hf_context, + spicontext); + if (stcontext) { + /* unregister nfc device */ + nfc_digital_unregister_device(stcontext->ddev); + + /* free the nfc device object */ + nfc_digital_free_device(stcontext->ddev); + + /* free GPIO pins */ + gpio_free(stcontext->st95hf_enable_gpio); + + /* disable regulator */ + if (stcontext->st95hf_supply) + regulator_disable(stcontext->st95hf_supply); + } + + return 0; +} + +/* Register as SPI protocol driver */ +static struct spi_driver st95hf_driver = { + .driver = { + .name = "st95hf", + .owner = THIS_MODULE, + }, + .id_table = st95hf_id, + .probe = st95hf_probe, + .remove = st95hf_remove, +}; + +/* module_spi_driver is helpler macro for registering a SPI driver */ +module_spi_driver(st95hf_driver); + +MODULE_AUTHOR("Shikha Singh <shikha.singh@st.com>"); +MODULE_DESCRIPTION("ST95HF SPI protocol driver ver " VERSION); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL v2"); -- 1.8.2.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support Shikha Singh @ 2015-10-22 6:24 ` Samuel Ortiz 2015-10-26 5:57 ` Shikha SINGH 2015-11-06 9:13 ` Shikha SINGH 0 siblings, 2 replies; 7+ messages in thread From: Samuel Ortiz @ 2015-10-22 6:24 UTC (permalink / raw) To: Shikha Singh Cc: aloisio.almeida, lauro.venancio, linux-wireless, linux-nfc, raunaque.quaiser, manoj.kumar, sylvain.fidelis, patrick.sohn Hi Shikha, On Sat, Sep 12, 2015 at 03:21:34AM -0400, Shikha Singh wrote: > diff --git a/drivers/nfc/st95hf/Makefile b/drivers/nfc/st95hf/Makefile > new file mode 100644 > index 0000000..2d8f8f3 > --- /dev/null > +++ b/drivers/nfc/st95hf/Makefile > @@ -0,0 +1,6 @@ > +# > +# Makefile for STMicroelectronics NFC transceiver ST95HF > +# # > + > +obj-$(CONFIG_NFC_ST95HF) += st_transceiver.o We should be more specific and call it st_nfc_transceiver for example. > +/* Function to send user provided buffer to ST95HF through SPI */ > +int spi_send_to_st95hf(struct spi_context *spicontext, > + unsigned char *buffertx, int datalen, > + enum req_type reqtype) To be consistent with the rest of your API, this one should be called st95hf_spi_send(). It obviously implies that it is sending packets to the transceiver. > +{ > + struct spi_message m; > + int result = 0; > + struct spi_device *spidev = spicontext->spidev; > + struct spi_transfer tx_transfer = { > + .rx_buf = NULL, > + .tx_buf = buffertx, > + .len = datalen, > + .cs_change = 0, > + .bits_per_word = 0, > + .delay_usecs = 0, > + .speed_hz = 0, > + }; You don't need to explicitely set those fields to NULL or 0, this one could be simplified to: struct spi_transfer t = { .tx_buf = buffertx, .len = datalen, }; > + spicontext->reply_from_st95 = 0; > + > + if (reqtype == SYNC) > + spicontext->req_issync = true; > + else > + spicontext->req_issync = false; > + > + spi_message_init(&m); > + spi_message_add_tail(&tx_transfer, &m); > + > + result = spi_sync(spidev, &m); > + if (result) { > + dev_err(&spidev->dev, > + "error: sending cmd to st95hf using SPI\n"); > + return result; > + } > + > + if (reqtype == ASYNC) { /* return for asynchronous or no-wait case */ > + return 0; > + } > + > + do { > + result = wait_event_interruptible_timeout( > + spicontext->st95wait_queue, > + spicontext->reply_from_st95 == 1, > + 1000); > + } while (result < 0); If result is < 0 it means your transfer got interrupted by a signal, there is no point in looping around result. You may just want to return result in that case. A couple more comments here: - A completion is probably enough for what you're trying to achieve. - This is racy: If you have 2 threads calling spi_send_to_st95hf() at the same time they may end up waiting on the waitqueue at the same time as well. The first interrupt that comes will wake both at the same time although it should not. In order to avoid that race, you need to synchronize the calls to spi_sync with e.g. a mutex so that you don't issue an spi_sync while someone is already on the waitqueue or sleeping for completion. > + > + if (result == 0) { > + dev_err(&spidev->dev, "error: response not ready timeout\n"); > + return -ETIMEDOUT; > + } > + > + if (result > 0) > + result = 0; > + > + return result; > +} > +EXPORT_SYMBOL_GPL(spi_send_to_st95hf); > + > +/* Function to Receive command Response */ > +int spi_receive_response(struct spi_context *spicontext, > + unsigned char *receivebuff, > + int *len) 2 things: - Let's call that one st95hf_spi_recv_response() - It typically should return the number of read bytes, instead of passing a len pointer to the argument list. > +{ > + struct spi_transfer tx_takeresponse1; > + struct spi_transfer tx_takeresponse2; > + struct spi_transfer tx_takedata; > + struct spi_message m; > + unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE; > + int ret = 0; > + > + struct spi_device *spidev = spicontext->spidev; > + > + *len = 0; > + > + memset(&tx_takeresponse1, 0x0, sizeof(struct spi_transfer)); > + memset(&tx_takeresponse2, 0x0, sizeof(struct spi_transfer)); > + memset(&tx_takedata, 0x0, sizeof(struct spi_transfer)); > + > + tx_takeresponse1.tx_buf = &readdata_cmd; > + tx_takeresponse1.len = 1; > + > + tx_takeresponse2.rx_buf = receivebuff; > + /* 1 byte Response code + 1 byte length of data */ > + tx_takeresponse2.len = 2; > + /* Dont allow to make chipselect high */ > + tx_takeresponse2.cs_change = 1; > + > + spi_message_init(&m); > + spi_message_add_tail(&tx_takeresponse1, &m); > + spi_message_add_tail(&tx_takeresponse2, &m); So this whole block of code could be simplified to: struct spi_transfer t[2] = { { .tx_buf = &readdata_cmd, .len = 1, }, { .rx_buf = receive_buff, .len = 2 , .cs_change = 1, }, }; spi_message_init(&m); spi_message_add_tail(&t[0], &m); spi_message_add_tail(&t[1], &m); > + ret = spi_sync(spidev, &m); > + if (ret) > + return ret; > + > + /* 2 bytes are already read */ > + *len = 2; > + > + /*support of long frame*/ Nitpick: Please add a space after /* and before */ > + if (receivebuff[0] & 0x60) > + *len += (((receivebuff[0] & 0x60) >> 5) << 8) | receivebuff[1]; > + else > + *len += receivebuff[1]; > + > + /* Now make a transfer to take only relevant data */ > + tx_takedata.rx_buf = &receivebuff[2]; > + tx_takedata.len = (*len) - 2; > + tx_takedata.cs_change = 0; > + > + spi_message_init(&m); > + spi_message_add_tail(&tx_takedata, &m); > + > + return spi_sync(spidev, &m); > +} > +EXPORT_SYMBOL_GPL(spi_receive_response); > + > +int spi_receive_echo_response(struct spi_context *spicontext, > + unsigned char *receivebuff) Similar comment, please call it st95hf_recv_echo(). > +{ > + struct spi_transfer tx_takeresponse1; > + struct spi_transfer tx_takedata; > + struct spi_message m; > + unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE; > + struct spi_device *spidev = spicontext->spidev; > + > + memset(&tx_takeresponse1, 0x0, sizeof(struct spi_transfer)); > + memset(&tx_takedata, 0x0, sizeof(struct spi_transfer)); > + > + tx_takeresponse1.tx_buf = &readdata_cmd; > + tx_takeresponse1.len = 1; > + tx_takeresponse1.rx_buf = NULL; > + > + tx_takedata.rx_buf = receivebuff; > + tx_takedata.tx_buf = NULL; > + tx_takedata.len = 1; > + > + spi_message_init(&m); > + spi_message_add_tail(&tx_takeresponse1, &m); > + spi_message_add_tail(&tx_takedata, &m); Similar comment as well, this can be simplified as described above. > + return spi_sync(spidev, &m); > +} > +EXPORT_SYMBOL_GPL(spi_receive_echo_response); > diff --git a/drivers/nfc/st95hf/spi.h b/drivers/nfc/st95hf/spi.h > new file mode 100644 > index 0000000..aa3eea0d > --- /dev/null > +++ b/drivers/nfc/st95hf/spi.h > @@ -0,0 +1,45 @@ > + /* > + * ----------------------------------------------------------------------------- > + * drivers/nfc/st95hf/spi.h functions declarations for SPI communication > + * ----------------------------------------------------------------------------- > + * > + * Copyright (C) 2015 STMicroelectronics – All Rights Reserved > + * Author: Shikha Singh <shikha.singh@st.com> > + * > + * May be copied or modified under the terms of the GNU General Public > + * License Version 2.0 only. See linux/COPYING for more information. > + * --------------------------------------------------------------------------- > + */ > + > +#ifndef __LINUX_ST95HF_SPI_H > +#define __LINUX_ST95HF_SPI_H > + > +#include <linux/spi/spi.h> > + > +struct spi_context { struct st95hf_spi_context would be more apropriate. > + int reply_from_st95; > + wait_queue_head_t st95wait_queue; I think those 2 can easily be replaced by a simple completion structure. > +static irqreturn_t irq_handler(int irq, void *st95hfcontext) > +{ > + struct st95hf_context *stcontext = > + (struct st95hf_context *)st95hfcontext; > + > + if (stcontext->spicontext.req_issync) { > + stcontext->spicontext.reply_from_st95 = 1; > + wake_up_interruptible(&stcontext->spicontext.st95wait_queue); > + return IRQ_HANDLED; > + } > + > + return IRQ_WAKE_THREAD; > +} Do you really need a specific IRQ handler for that ? Can't you do it from the threaded interrupt context ? > +static irqreturn_t irq_thread_handler(int irq, void *st95hfcontext) > +{ > + int result; > + int res_len; > + int skb_len; > + static bool wtx; > + struct param_list new_params[1]; > + struct st95hf_context *stcontext = > + (struct st95hf_context *)st95hfcontext; > + unsigned char error_byte; > + struct device *dev = &stcontext->nfcdev->dev; > + struct nfc_digital_dev *nfcddev = stcontext->ddev; > + unsigned char val_mm; > + > + struct st95_digital_cmd_complete_arg *cb_arg = > + stcontext->complete_cb_arg; > + > + if (!cb_arg) { > + dev_err(dev, "cb_arg is NULL in threaded ISR\n"); > + BUG(); > + } > + > + result = spi_receive_response(&stcontext->spicontext, > + cb_arg->skb_resp->data, > + &res_len); > + if (result) { > + dev_err(dev, "res receive threaded ISR err = 0x%x\n", result); > + goto end; > + } > + > + if (*((cb_arg->skb_resp->data) + 2) == WTX_REQ_FROM_TAG) { > + /* Request for new FWT from tag */ FWT ? > + result = iso14443_config_fdt(stcontext, > + (*((cb_arg->skb_resp->data) + 3) > + & 0x3f)); > + if (result) { > + dev_err(dev, "Config. setting error on WTX req, err = 0x%x\n", > + result); > + goto end; > + } > + wtx = true; > + > + /* ASYNC req as no response expected */ > + new_params[0].param_offset = 1; > + new_params[0].new_param_val = > + *((cb_arg->skb_resp->data) + 3); > + > + result = st95hf_send_cmd(stcontext, > + WTX_RESPONSE, > + 1, > + new_params); > + if (result) { > + dev_err(dev, "WTX response send, err = 0x%x\n", result); > + goto end; > + } > + return IRQ_HANDLED; > + } A few comments: - You probably want to define a struct sk_buff *skb_resp = cb_arg->skb_resp - *((cb_arg->skb_resp->data) + 2) becomes skb_resp->data[2] - This handler is almost 200 lines of code long, it could be splitted in smaller routines: * One for handling FWT from tag * One for handling I/O errors * One for actually processing the response > +static struct nfc_digital_ops st95hf_nfc_digital_ops = { > + .in_configure_hw = st95hf_in_configure_hw, > + .in_send_cmd = st95hf_in_send_cmd, > + > + .tg_listen = st95hf_tg_listen, > + .tg_configure_hw = st95hf_tg_configure_hw, > + .tg_send_cmd = st95hf_tg_send_cmd, > + .tg_get_rf_tech = st95hf_tg_get_rf_tech, > + > + .switch_rf = st95hf_switch_rf, > + .abort_cmd = st95hf_abort_cmd, All the above ops can be static. > +static int st95hf_probe(struct spi_device *nfc_spi_dev) > +{ > + int ret; > + > + struct st95hf_context *st95context; > + struct spi_context *spicontext; > + struct device_node *np = nfc_spi_dev->dev.of_node; > + > + pr_info("ST SPI SLAVE DRIVER (ST95HF R/W 14443A/B) PROBE CALLED\n"); > + > + st95context = devm_kzalloc(&nfc_spi_dev->dev, > + sizeof(struct st95hf_context), > + GFP_KERNEL); > + if (!st95context) > + return -ENOMEM; > + > + spicontext = &st95context->spicontext; > + > + spicontext->spidev = nfc_spi_dev; > + > + st95context->fwi = cmd_array[ISO14443A_PROTOCOL_SELECT].cmd_params[2]; > + > + if (of_get_property(np, "st95hfvin-supply", NULL)) { Please use device_property_present to be firmware API agnostic. Cheers, Samuel. ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support 2015-10-22 6:24 ` Samuel Ortiz @ 2015-10-26 5:57 ` Shikha SINGH 2015-11-06 9:13 ` Shikha SINGH 1 sibling, 0 replies; 7+ messages in thread From: Shikha SINGH @ 2015-10-26 5:57 UTC (permalink / raw) To: Samuel Ortiz Cc: aloisio.almeida@openbossa.org, lauro.venancio@openbossa.org, linux-wireless@vger.kernel.org, linux-nfc@lists.01.org, Raunaque Mujeeb QUAISER, Manoj KUMAR, Sylvain FIDELIS, Patrick SOHN DQpIaSBTYW11ZWwsDQoJVGhhbmtzIGZvciB5b3VyIHJldmlldy4NCg0KDQpPbiBTYXQsIFNlcCAx MiwgMjAxNSBhdCAwMzoyMTozNEFNIC0wNDAwLCBTaGlraGEgU2luZ2ggd3JvdGU6DQo+IGRpZmYg LS1naXQgYS9kcml2ZXJzL25mYy9zdDk1aGYvTWFrZWZpbGUgYi9kcml2ZXJzL25mYy9zdDk1aGYv TWFrZWZpbGUgDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0IGluZGV4IDAwMDAwMDAuLjJkOGY4ZjMN Cj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL25mYy9zdDk1aGYvTWFrZWZpbGUNCj4g QEAgLTAsMCArMSw2IEBADQo+ICsjDQo+ICsjIE1ha2VmaWxlIGZvciBTVE1pY3JvZWxlY3Ryb25p Y3MgTkZDIHRyYW5zY2VpdmVyIFNUOTVIRiAjICMNCj4gKw0KPiArb2JqLSQoQ09ORklHX05GQ19T VDk1SEYpCSs9IHN0X3RyYW5zY2VpdmVyLm8NCldlIHNob3VsZCBiZSBtb3JlIHNwZWNpZmljIGFu ZCBjYWxsIGl0IHN0X25mY190cmFuc2NlaXZlciBmb3IgZXhhbXBsZS4NCg0KT2suDQoNCj4gKy8q IEZ1bmN0aW9uIHRvIHNlbmQgdXNlciBwcm92aWRlZCBidWZmZXIgdG8gU1Q5NUhGIHRocm91Z2gg U1BJICovIGludCANCj4gK3NwaV9zZW5kX3RvX3N0OTVoZihzdHJ1Y3Qgc3BpX2NvbnRleHQgKnNw aWNvbnRleHQsDQo+ICsJCSAgICAgICB1bnNpZ25lZCBjaGFyICpidWZmZXJ0eCwgaW50IGRhdGFs ZW4sDQo+ICsJCSAgICAgICBlbnVtIHJlcV90eXBlIHJlcXR5cGUpDQpUbyBiZSBjb25zaXN0ZW50 IHdpdGggdGhlIHJlc3Qgb2YgeW91ciBBUEksIHRoaXMgb25lIHNob3VsZCBiZSBjYWxsZWQgc3Q5 NWhmX3NwaV9zZW5kKCkuIEl0IG9idmlvdXNseSBpbXBsaWVzIHRoYXQgaXQgaXMgc2VuZGluZyBw YWNrZXRzIHRvIHRoZSB0cmFuc2NlaXZlci4NCg0KT2suDQoNCj4gK3sNCj4gKwlzdHJ1Y3Qgc3Bp X21lc3NhZ2UgbTsNCj4gKwlpbnQgcmVzdWx0ID0gMDsNCj4gKwlzdHJ1Y3Qgc3BpX2RldmljZSAq c3BpZGV2ID0gc3BpY29udGV4dC0+c3BpZGV2Ow0KPiArCXN0cnVjdCBzcGlfdHJhbnNmZXIgdHhf dHJhbnNmZXIgPSB7DQo+ICsJCS5yeF9idWYgPSBOVUxMLA0KPiArCQkudHhfYnVmID0gYnVmZmVy dHgsDQo+ICsJCS5sZW4gPSBkYXRhbGVuLA0KPiArCQkuY3NfY2hhbmdlID0gMCwNCj4gKwkJLmJp dHNfcGVyX3dvcmQgPSAwLA0KPiArCQkuZGVsYXlfdXNlY3MgPSAwLA0KPiArCQkuc3BlZWRfaHog PSAwLA0KPiArCX07DQpZb3UgZG9uJ3QgbmVlZCB0byBleHBsaWNpdGVseSBzZXQgdGhvc2UgZmll bGRzIHRvIE5VTEwgb3IgMCwgdGhpcyBvbmUgY291bGQgYmUgc2ltcGxpZmllZCB0bzoNCg0Kc3Ry dWN0IHNwaV90cmFuc2ZlciB0ID0geyAudHhfYnVmID0gYnVmZmVydHgsIC5sZW4gPSBkYXRhbGVu LCB9Ow0KDQpPay4NCg0KPiArCXNwaWNvbnRleHQtPnJlcGx5X2Zyb21fc3Q5NSA9IDA7DQo+ICsN Cj4gKwlpZiAocmVxdHlwZSA9PSBTWU5DKQ0KPiArCQlzcGljb250ZXh0LT5yZXFfaXNzeW5jID0g dHJ1ZTsNCj4gKwllbHNlDQo+ICsJCXNwaWNvbnRleHQtPnJlcV9pc3N5bmMgPSBmYWxzZTsNCj4g Kw0KPiArCXNwaV9tZXNzYWdlX2luaXQoJm0pOw0KPiArCXNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0 eF90cmFuc2ZlciwgJm0pOw0KPiArDQo+ICsJcmVzdWx0ID0gc3BpX3N5bmMoc3BpZGV2LCAmbSk7 DQo+ICsJaWYgKHJlc3VsdCkgew0KPiArCQlkZXZfZXJyKCZzcGlkZXYtPmRldiwNCj4gKwkJCSJl cnJvcjogc2VuZGluZyBjbWQgdG8gc3Q5NWhmIHVzaW5nIFNQSVxuIik7DQo+ICsJCXJldHVybiBy ZXN1bHQ7DQo+ICsJfQ0KPiArDQo+ICsJaWYgKHJlcXR5cGUgPT0gQVNZTkMpIHsgLyogcmV0dXJu IGZvciBhc3luY2hyb25vdXMgb3Igbm8td2FpdCBjYXNlICovDQo+ICsJCXJldHVybiAwOw0KPiAr CX0NCj4gKw0KPiArCWRvIHsNCj4gKwkJcmVzdWx0ID0gd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxl X3RpbWVvdXQoDQo+ICsJCQkJc3BpY29udGV4dC0+c3Q5NXdhaXRfcXVldWUsDQo+ICsJCQkJc3Bp Y29udGV4dC0+cmVwbHlfZnJvbV9zdDk1ID09IDEsDQo+ICsJCQkJMTAwMCk7DQo+ICsJfSB3aGls ZSAocmVzdWx0IDwgMCk7DQpJZiByZXN1bHQgaXMgPCAwIGl0IG1lYW5zIHlvdXIgdHJhbnNmZXIg Z290IGludGVycnVwdGVkIGJ5IGEgc2lnbmFsLCB0aGVyZSBpcyBubyBwb2ludCBpbiBsb29waW5n IGFyb3VuZCByZXN1bHQuIFlvdSBtYXkganVzdCB3YW50IHRvIHJldHVybiByZXN1bHQgaW4gdGhh dCBjYXNlLg0KDQpBZ3JlZS4gSSB3aWxsIGNvcnJlY3QgaW4gbmV4dCB2ZXJzaW9uLg0KDQpBIGNv dXBsZSBtb3JlIGNvbW1lbnRzIGhlcmU6DQotIEEgY29tcGxldGlvbiBpcyBwcm9iYWJseSBlbm91 Z2ggZm9yIHdoYXQgeW91J3JlIHRyeWluZyB0byBhY2hpZXZlLg0KDQpZZXMuIEkgd2lsbCBtYWtl IGNoYW5nZXMgYWNjb3JkaW5nbHkuDQoNCi0gVGhpcyBpcyByYWN5OiBJZiB5b3UgaGF2ZSAyIHRo cmVhZHMgY2FsbGluZyBzcGlfc2VuZF90b19zdDk1aGYoKSBhdA0KICB0aGUgc2FtZSB0aW1lIHRo ZXkgbWF5IGVuZCB1cCB3YWl0aW5nIG9uIHRoZSB3YWl0cXVldWUgYXQgdGhlIHNhbWUNCiAgdGlt ZSBhcyB3ZWxsLiBUaGUgZmlyc3QgaW50ZXJydXB0IHRoYXQgY29tZXMgd2lsbCB3YWtlIGJvdGgg YXQgdGhlDQogIHNhbWUgdGltZSBhbHRob3VnaCBpdCBzaG91bGQgbm90Lg0KICBJbiBvcmRlciB0 byBhdm9pZCB0aGF0IHJhY2UsIHlvdSBuZWVkIHRvIHN5bmNocm9uaXplIHRoZSBjYWxscyB0bw0K ICBzcGlfc3luYyB3aXRoIGUuZy4gYSBtdXRleCBzbyB0aGF0IHlvdSBkb24ndCBpc3N1ZSBhbiBz cGlfc3luYyB3aGlsZQ0KICBzb21lb25lIGlzIGFscmVhZHkgb24gdGhlIHdhaXRxdWV1ZSBvciBz bGVlcGluZyBmb3IgY29tcGxldGlvbi4NCg0KT2suIEFsdGhvdWdoIGF0IHByZXNlbnQgdGhlcmUg aXMgbm8gc2l0dWF0aW9uIHdoZXJlIHNwaV9zZW5kX3RvX3N0OTVoZigpIGNhbiBiZSBjYWxsZWQg c2ltdWx0YW5lb3VzbHkNCmJ1dCBJIHdpbGwgYWNjb21tb2RhdGUgeW91ciBzdWdnZXN0aW9uIHRv IGhhdmUgYSBzYWZlIGNvZGUuIA0KDQo+ICsNCj4gKwlpZiAocmVzdWx0ID09IDApIHsNCj4gKwkJ ZGV2X2Vycigmc3BpZGV2LT5kZXYsICJlcnJvcjogcmVzcG9uc2Ugbm90IHJlYWR5IHRpbWVvdXRc biIpOw0KPiArCQlyZXR1cm4gLUVUSU1FRE9VVDsNCj4gKwl9DQo+ICsNCj4gKwlpZiAocmVzdWx0 ID4gMCkNCj4gKwkJcmVzdWx0ID0gMDsNCj4gKw0KPiArCXJldHVybiByZXN1bHQ7DQo+ICt9DQo+ ICtFWFBPUlRfU1lNQk9MX0dQTChzcGlfc2VuZF90b19zdDk1aGYpOw0KPiArDQo+ICsvKiBGdW5j dGlvbiB0byBSZWNlaXZlIGNvbW1hbmQgUmVzcG9uc2UgKi8gaW50IA0KPiArc3BpX3JlY2VpdmVf cmVzcG9uc2Uoc3RydWN0IHNwaV9jb250ZXh0ICpzcGljb250ZXh0LA0KPiArCQkJIHVuc2lnbmVk IGNoYXIgKnJlY2VpdmVidWZmLA0KPiArCQkJIGludCAqbGVuKQ0KMiB0aGluZ3M6DQoNCi0gTGV0 J3MgY2FsbCB0aGF0IG9uZSBzdDk1aGZfc3BpX3JlY3ZfcmVzcG9uc2UoKQ0KDQpPay4NCg0KLSBJ dCB0eXBpY2FsbHkgc2hvdWxkIHJldHVybiB0aGUgbnVtYmVyIG9mIHJlYWQgYnl0ZXMsIGluc3Rl YWQgb2YNCiAgcGFzc2luZyBhIGxlbiBwb2ludGVyIHRvIHRoZSBhcmd1bWVudCBsaXN0Lg0KDQpP ay4NCg0KDQo+ICt7DQo+ICsJc3RydWN0IHNwaV90cmFuc2ZlciB0eF90YWtlcmVzcG9uc2UxOw0K PiArCXN0cnVjdCBzcGlfdHJhbnNmZXIgdHhfdGFrZXJlc3BvbnNlMjsNCj4gKwlzdHJ1Y3Qgc3Bp X3RyYW5zZmVyIHR4X3Rha2VkYXRhOw0KPiArCXN0cnVjdCBzcGlfbWVzc2FnZSBtOw0KPiArCXVu c2lnbmVkIGNoYXIgcmVhZGRhdGFfY21kID0gU1Q5NUhGX0NPTU1BTkRfUkVDRUlWRTsNCj4gKwlp bnQgcmV0ID0gMDsNCj4gKw0KPiArCXN0cnVjdCBzcGlfZGV2aWNlICpzcGlkZXYgPSBzcGljb250 ZXh0LT5zcGlkZXY7DQo+ICsNCj4gKwkqbGVuID0gMDsNCj4gKw0KPiArCW1lbXNldCgmdHhfdGFr ZXJlc3BvbnNlMSwgMHgwLCBzaXplb2Yoc3RydWN0IHNwaV90cmFuc2ZlcikpOw0KPiArCW1lbXNl dCgmdHhfdGFrZXJlc3BvbnNlMiwgMHgwLCBzaXplb2Yoc3RydWN0IHNwaV90cmFuc2ZlcikpOw0K PiArCW1lbXNldCgmdHhfdGFrZWRhdGEsIDB4MCwgc2l6ZW9mKHN0cnVjdCBzcGlfdHJhbnNmZXIp KTsNCj4gKw0KPiArCXR4X3Rha2VyZXNwb25zZTEudHhfYnVmID0gJnJlYWRkYXRhX2NtZDsNCj4g Kwl0eF90YWtlcmVzcG9uc2UxLmxlbiA9IDE7DQo+ICsNCj4gKwl0eF90YWtlcmVzcG9uc2UyLnJ4 X2J1ZiA9IHJlY2VpdmVidWZmOw0KPiArCS8qIDEgYnl0ZSAgUmVzcG9uc2UgY29kZSArIDEgYnl0 ZSAgbGVuZ3RoIG9mIGRhdGEgKi8NCj4gKwl0eF90YWtlcmVzcG9uc2UyLmxlbiA9IDI7DQo+ICsJ LyogRG9udCBhbGxvdyB0byBtYWtlIGNoaXBzZWxlY3QgaGlnaCAqLw0KPiArCXR4X3Rha2VyZXNw b25zZTIuY3NfY2hhbmdlID0gMTsNCj4gKw0KPiArCXNwaV9tZXNzYWdlX2luaXQoJm0pOw0KPiAr CXNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0eF90YWtlcmVzcG9uc2UxLCAmbSk7DQo+ICsJc3BpX21l c3NhZ2VfYWRkX3RhaWwoJnR4X3Rha2VyZXNwb25zZTIsICZtKTsNCg0KU28gdGhpcyB3aG9sZSBi bG9jayBvZiBjb2RlIGNvdWxkIGJlIHNpbXBsaWZpZWQgdG86DQoNCnN0cnVjdCBzcGlfdHJhbnNm ZXIgdFsyXSA9IHsgeyAudHhfYnVmID0gJnJlYWRkYXRhX2NtZCwgLmxlbiA9IDEsIH0sDQogICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHsgLnJ4X2J1ZiA9IHJlY2VpdmVfYnVmZiwgIC5sZW4g PSAyICwgLmNzX2NoYW5nZSA9IDEsIH0sIH07DQoNCnNwaV9tZXNzYWdlX2luaXQoJm0pOw0Kc3Bp X21lc3NhZ2VfYWRkX3RhaWwoJnRbMF0sICZtKTsNCnNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0WzFd LCAmbSk7DQoNCk9rLiANCg0KPiArCXJldCA9IHNwaV9zeW5jKHNwaWRldiwgJm0pOw0KPiArCWlm IChyZXQpDQo+ICsJCXJldHVybiByZXQ7DQo+ICsNCj4gKwkvKiAyIGJ5dGVzIGFyZSBhbHJlYWR5 IHJlYWQgKi8NCj4gKwkqbGVuID0gMjsNCj4gKw0KPiArCS8qc3VwcG9ydCBvZiBsb25nIGZyYW1l Ki8NCk5pdHBpY2s6IFBsZWFzZSBhZGQgYSBzcGFjZSBhZnRlciAvKiBhbmQgYmVmb3JlICovDQoN Ck9rLiANCg0KPiArCWlmIChyZWNlaXZlYnVmZlswXSAmIDB4NjApDQo+ICsJCSpsZW4gKz0gKCgo cmVjZWl2ZWJ1ZmZbMF0gJiAweDYwKSA+PiA1KSA8PCA4KSB8IHJlY2VpdmVidWZmWzFdOw0KPiAr CWVsc2UNCj4gKwkJKmxlbiArPSByZWNlaXZlYnVmZlsxXTsNCj4gKw0KPiArCS8qIE5vdyBtYWtl IGEgdHJhbnNmZXIgdG8gdGFrZSBvbmx5IHJlbGV2YW50IGRhdGEgKi8NCj4gKwl0eF90YWtlZGF0 YS5yeF9idWYgPSAmcmVjZWl2ZWJ1ZmZbMl07DQo+ICsJdHhfdGFrZWRhdGEubGVuID0gKCpsZW4p IC0gMjsNCj4gKwl0eF90YWtlZGF0YS5jc19jaGFuZ2UgPSAwOw0KPiArDQo+ICsJc3BpX21lc3Nh Z2VfaW5pdCgmbSk7DQo+ICsJc3BpX21lc3NhZ2VfYWRkX3RhaWwoJnR4X3Rha2VkYXRhLCAmbSk7 DQo+ICsNCj4gKwlyZXR1cm4gc3BpX3N5bmMoc3BpZGV2LCAmbSk7DQo+ICt9DQo+ICtFWFBPUlRf U1lNQk9MX0dQTChzcGlfcmVjZWl2ZV9yZXNwb25zZSk7DQo+ICsNCj4gK2ludCBzcGlfcmVjZWl2 ZV9lY2hvX3Jlc3BvbnNlKHN0cnVjdCBzcGlfY29udGV4dCAqc3BpY29udGV4dCwNCj4gKwkJCSAg ICAgIHVuc2lnbmVkIGNoYXIgKnJlY2VpdmVidWZmKQ0KU2ltaWxhciBjb21tZW50LCBwbGVhc2Ug Y2FsbCBpdCBzdDk1aGZfcmVjdl9lY2hvKCkuDQoNCk9rLg0KDQo+ICt7DQo+ICsJc3RydWN0IHNw aV90cmFuc2ZlciB0eF90YWtlcmVzcG9uc2UxOw0KPiArCXN0cnVjdCBzcGlfdHJhbnNmZXIgdHhf dGFrZWRhdGE7DQo+ICsJc3RydWN0IHNwaV9tZXNzYWdlIG07DQo+ICsJdW5zaWduZWQgY2hhciBy ZWFkZGF0YV9jbWQgPSBTVDk1SEZfQ09NTUFORF9SRUNFSVZFOw0KPiArCXN0cnVjdCBzcGlfZGV2 aWNlICpzcGlkZXYgPSBzcGljb250ZXh0LT5zcGlkZXY7DQo+ICsNCj4gKwltZW1zZXQoJnR4X3Rh a2VyZXNwb25zZTEsIDB4MCwgc2l6ZW9mKHN0cnVjdCBzcGlfdHJhbnNmZXIpKTsNCj4gKwltZW1z ZXQoJnR4X3Rha2VkYXRhLCAweDAsIHNpemVvZihzdHJ1Y3Qgc3BpX3RyYW5zZmVyKSk7DQo+ICsN Cj4gKwl0eF90YWtlcmVzcG9uc2UxLnR4X2J1ZiA9ICZyZWFkZGF0YV9jbWQ7DQo+ICsJdHhfdGFr ZXJlc3BvbnNlMS5sZW4gPSAxOw0KPiArCXR4X3Rha2VyZXNwb25zZTEucnhfYnVmID0gTlVMTDsN Cj4gKw0KPiArCXR4X3Rha2VkYXRhLnJ4X2J1ZiA9IHJlY2VpdmVidWZmOw0KPiArCXR4X3Rha2Vk YXRhLnR4X2J1ZiA9IE5VTEw7DQo+ICsJdHhfdGFrZWRhdGEubGVuID0gMTsNCj4gKw0KPiArCXNw aV9tZXNzYWdlX2luaXQoJm0pOw0KPiArCXNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0eF90YWtlcmVz cG9uc2UxLCAmbSk7DQo+ICsJc3BpX21lc3NhZ2VfYWRkX3RhaWwoJnR4X3Rha2VkYXRhLCAmbSk7 DQpTaW1pbGFyIGNvbW1lbnQgYXMgd2VsbCwgdGhpcyBjYW4gYmUgc2ltcGxpZmllZCBhcyBkZXNj cmliZWQgYWJvdmUuDQoNCk9rLg0KDQo+ICsJcmV0dXJuIHNwaV9zeW5jKHNwaWRldiwgJm0pOw0K PiArfQ0KPiArRVhQT1JUX1NZTUJPTF9HUEwoc3BpX3JlY2VpdmVfZWNob19yZXNwb25zZSk7DQo+ IGRpZmYgLS1naXQgYS9kcml2ZXJzL25mYy9zdDk1aGYvc3BpLmggYi9kcml2ZXJzL25mYy9zdDk1 aGYvc3BpLmggbmV3IA0KPiBmaWxlIG1vZGUgMTAwNjQ0IGluZGV4IDAwMDAwMDAuLmFhM2VlYTBk DQo+IC0tLSAvZGV2L251bGwNCj4gKysrIGIvZHJpdmVycy9uZmMvc3Q5NWhmL3NwaS5oDQo+IEBA IC0wLDAgKzEsNDUgQEANCj4gKyAvKg0KPiArICogDQo+ICsgLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCj4gKyAtLS0t LS0tLS0NCj4gKyAqIGRyaXZlcnMvbmZjL3N0OTVoZi9zcGkuaCBmdW5jdGlvbnMgZGVjbGFyYXRp b25zIGZvciBTUEkgDQo+ICsgY29tbXVuaWNhdGlvbg0KPiArICogDQo+ICsgLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N Cj4gKyAtLS0tLS0tLS0NCj4gKyAqDQo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTUgU1RNaWNyb2Vs ZWN0cm9uaWNzIOKAkyBBbGwgUmlnaHRzIFJlc2VydmVkDQo+ICsgKiBBdXRob3I6IFNoaWtoYSBT aW5naCA8c2hpa2hhLnNpbmdoQHN0LmNvbT4NCj4gKyAqDQo+ICsgKiBNYXkgYmUgY29waWVkIG9y IG1vZGlmaWVkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgDQo+ICsgUHVibGlj DQo+ICsgKiBMaWNlbnNlIFZlcnNpb24gMi4wIG9ubHkuIFNlZSBsaW51eC9DT1BZSU5HIGZvciBt b3JlIGluZm9ybWF0aW9uLg0KPiArICogIA0KPiArIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQo+ICsgLS0tLS0tLQ0K PiArICovDQo+ICsNCj4gKyNpZm5kZWYgX19MSU5VWF9TVDk1SEZfU1BJX0gNCj4gKyNkZWZpbmUg X19MSU5VWF9TVDk1SEZfU1BJX0gNCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4L3NwaS9zcGkuaD4N Cj4gKw0KPiArc3RydWN0IHNwaV9jb250ZXh0IHsNCnN0cnVjdCBzdDk1aGZfc3BpX2NvbnRleHQg d291bGQgYmUgbW9yZSBhcHJvcHJpYXRlLg0KDQpPay4NCg0KPiArCWludCByZXBseV9mcm9tX3N0 OTU7DQo+ICsJd2FpdF9xdWV1ZV9oZWFkX3Qgc3Q5NXdhaXRfcXVldWU7DQpJIHRoaW5rIHRob3Nl IDIgY2FuIGVhc2lseSBiZSByZXBsYWNlZCBieSBhIHNpbXBsZSBjb21wbGV0aW9uIHN0cnVjdHVy ZS4NCg0KQWdyZWUuIEkgd2lsbCByZXBsYWNlIGl0IHdpdGggY29tcGxldGlvbiBzdHJ1Y3R1cmUg b2Yga2VybmVsLg0KDQo+ICtzdGF0aWMgaXJxcmV0dXJuX3QgaXJxX2hhbmRsZXIoaW50IGlycSwg dm9pZCAgKnN0OTVoZmNvbnRleHQpIHsNCj4gKwlzdHJ1Y3Qgc3Q5NWhmX2NvbnRleHQgKnN0Y29u dGV4dCAgPQ0KPiArCQkoc3RydWN0IHN0OTVoZl9jb250ZXh0ICopc3Q5NWhmY29udGV4dDsNCj4g Kw0KPiArCWlmIChzdGNvbnRleHQtPnNwaWNvbnRleHQucmVxX2lzc3luYykgew0KPiArCQlzdGNv bnRleHQtPnNwaWNvbnRleHQucmVwbHlfZnJvbV9zdDk1ID0gMTsNCj4gKwkJd2FrZV91cF9pbnRl cnJ1cHRpYmxlKCZzdGNvbnRleHQtPnNwaWNvbnRleHQuc3Q5NXdhaXRfcXVldWUpOw0KPiArCQly ZXR1cm4gSVJRX0hBTkRMRUQ7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIElSUV9XQUtFX1RIUkVB RDsNCj4gK30NCkRvIHlvdSByZWFsbHkgbmVlZCBhIHNwZWNpZmljIElSUSBoYW5kbGVyIGZvciB0 aGF0ID8gQ2FuJ3QgeW91IGRvIGl0IGZyb20gdGhlIHRocmVhZGVkIGludGVycnVwdCBjb250ZXh0 ID8NCg0KQ3VycmVudGx5IHdlIGRvbid0IG5lZWQgdG8gcnVuIGFueSBzcGVjaWZpYyBjb2RlIGlu IGhhcmQgSVJRIGNvbnRleHQgc28geWVzIHdlIGNhbiB1c2Ugc2luZ2xlIHRocmVhZGVkIGludGVy cnVwdCBjb250ZXh0IGZvciBhbGwgY2FzZXMuDQpJIHdpbGwgbW9kaWZ5Lg0KDQo+ICtzdGF0aWMg aXJxcmV0dXJuX3QgaXJxX3RocmVhZF9oYW5kbGVyKGludCBpcnEsIHZvaWQgICpzdDk1aGZjb250 ZXh0KSANCj4gK3sNCj4gKwlpbnQgcmVzdWx0Ow0KPiArCWludCByZXNfbGVuOw0KPiArCWludCBz a2JfbGVuOw0KPiArCXN0YXRpYyBib29sIHd0eDsNCj4gKwlzdHJ1Y3QgcGFyYW1fbGlzdCBuZXdf cGFyYW1zWzFdOw0KPiArCXN0cnVjdCBzdDk1aGZfY29udGV4dCAqc3Rjb250ZXh0ICA9DQo+ICsJ CShzdHJ1Y3Qgc3Q5NWhmX2NvbnRleHQgKilzdDk1aGZjb250ZXh0Ow0KPiArCXVuc2lnbmVkIGNo YXIgZXJyb3JfYnl0ZTsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmc3Rjb250ZXh0LT5uZmNk ZXYtPmRldjsNCj4gKwlzdHJ1Y3QgbmZjX2RpZ2l0YWxfZGV2ICpuZmNkZGV2ID0gc3Rjb250ZXh0 LT5kZGV2Ow0KPiArCXVuc2lnbmVkIGNoYXIgdmFsX21tOw0KPiArDQo+ICsJc3RydWN0IHN0OTVf ZGlnaXRhbF9jbWRfY29tcGxldGVfYXJnICpjYl9hcmcgPQ0KPiArCQlzdGNvbnRleHQtPmNvbXBs ZXRlX2NiX2FyZzsNCj4gKw0KPiArCWlmICghY2JfYXJnKSB7DQo+ICsJCWRldl9lcnIoZGV2LCAi Y2JfYXJnIGlzIE5VTEwgaW4gdGhyZWFkZWQgSVNSXG4iKTsNCj4gKwkJQlVHKCk7DQo+ICsJfQ0K PiArDQo+ICsJcmVzdWx0ID0gc3BpX3JlY2VpdmVfcmVzcG9uc2UoJnN0Y29udGV4dC0+c3BpY29u dGV4dCwNCj4gKwkJCQkgICAgICBjYl9hcmctPnNrYl9yZXNwLT5kYXRhLA0KPiArCQkJCSAgICAg ICZyZXNfbGVuKTsNCj4gKwlpZiAocmVzdWx0KSB7DQo+ICsJCWRldl9lcnIoZGV2LCAicmVzIHJl Y2VpdmUgdGhyZWFkZWQgSVNSIGVyciA9IDB4JXhcbiIsIHJlc3VsdCk7DQo+ICsJCWdvdG8gZW5k Ow0KPiArCX0NCj4gKw0KPiArCWlmICgqKChjYl9hcmctPnNrYl9yZXNwLT5kYXRhKSArIDIpID09 IFdUWF9SRVFfRlJPTV9UQUcpIHsNCj4gKwkJLyogUmVxdWVzdCBmb3IgbmV3IEZXVCBmcm9tIHRh ZyAqLw0KRldUID8NCg0KRldUIGlzIEZyYW1lIFdhaXRpbmcgVGltZS4NCkFjY29yZGluZyB0byBJ U08tREVQIHByb3RvY29sLCB0YWcgY2FuIHNlbmQgdGhlIHJlcXVlc3QgdG8gcmVhZGVyIGZvciBu ZXcgd2FpdGluZyB0aW1lIHVzaW5nIFdUWCByZXF1ZXN0IChXYWl0aW5nIFRpbWUgZVh0ZW5zaW9u KSB3aGVuIHRhZyBuZWVkIG1vcmUgdGltZSBhdCBpdHMgZW5kIGZvciBwcm9jZXNzaW5nLg0KSW4g dGhpcyBzaXR1YXRpb24sIGluIHJlc3BvbnNlIG9mIFdUWCByZXF1ZXN0IHJlYWRlciBpcyBhbHNv IHJlcXVpcmVkIHRvIGJlIHJlLWNvbmZpZ3VyZWQgdG8gaW5jcmVhc2UgaXRzIHRpbWVvdXQuIA0K U28gdGhhdCByZWFkZXIgd2lsbCB3YWl0IGZvciByZXNwb25zZSBmcm9tIHRhZyBmb3IgdGhlIHN1 ZmZpY2llbnQgdGltZSBiZWZvcmUgZGVjbGFyaW5nIHRoZSB0aW1lb3V0IGVycm9yLiAgDQoNCg0K PiArCQlyZXN1bHQgPSBpc28xNDQ0M19jb25maWdfZmR0KHN0Y29udGV4dCwNCj4gKwkJCQkJICAg ICAoKigoY2JfYXJnLT5za2JfcmVzcC0+ZGF0YSkgKyAzKQ0KPiArCQkJCQkJJiAweDNmKSk7DQo+ ICsJCWlmIChyZXN1bHQpIHsNCj4gKwkJCWRldl9lcnIoZGV2LCAiQ29uZmlnLiBzZXR0aW5nIGVy cm9yIG9uIFdUWCByZXEsIGVyciA9IDB4JXhcbiIsDQo+ICsJCQkJcmVzdWx0KTsNCj4gKwkJCWdv dG8gZW5kOw0KPiArCQl9DQo+ICsJCXd0eCA9IHRydWU7DQo+ICsNCj4gKwkJLyogQVNZTkMgcmVx IGFzIG5vIHJlc3BvbnNlIGV4cGVjdGVkICovDQo+ICsJCW5ld19wYXJhbXNbMF0ucGFyYW1fb2Zm c2V0ID0gMTsNCj4gKwkJbmV3X3BhcmFtc1swXS5uZXdfcGFyYW1fdmFsID0NCj4gKwkJCSooKGNi X2FyZy0+c2tiX3Jlc3AtPmRhdGEpICsgMyk7DQo+ICsNCj4gKwkJcmVzdWx0ID0gc3Q5NWhmX3Nl bmRfY21kKHN0Y29udGV4dCwNCj4gKwkJCQkJIFdUWF9SRVNQT05TRSwNCj4gKwkJCQkJIDEsDQo+ ICsJCQkJCSBuZXdfcGFyYW1zKTsNCj4gKwkJaWYgKHJlc3VsdCkgew0KPiArCQkJZGV2X2Vycihk ZXYsICJXVFggcmVzcG9uc2Ugc2VuZCwgZXJyID0gMHgleFxuIiwgcmVzdWx0KTsNCj4gKwkJCWdv dG8gZW5kOw0KPiArCQl9DQo+ICsJCXJldHVybiBJUlFfSEFORExFRDsNCj4gKwl9DQpBIGZldyBj b21tZW50czoNCg0KLSBZb3UgcHJvYmFibHkgd2FudCB0byBkZWZpbmUgYSBzdHJ1Y3Qgc2tfYnVm ZiAqc2tiX3Jlc3AgPQ0KICBjYl9hcmctPnNrYl9yZXNwDQoNCk9rLiBJIHdpbGwgc2ltcGxpZnkg dGhlIGNvZGUgYnkgZGVmaW5pbmcgYSBsb2NhbCBzdHJ1Y3R1cmUgYXMgc3RydWN0IHNrX2J1ZmYg KnNrYl9yZXNwID0NCiAgY2JfYXJnLT5za2JfcmVzcC4gDQoNCi0gKigoY2JfYXJnLT5za2JfcmVz cC0+ZGF0YSkgKyAyKSBiZWNvbWVzIHNrYl9yZXNwLT5kYXRhWzJdDQoNCk9rLiBXaWxsIG1vZGlm eSB0aGUgd2hvbGUgY29kZSBhY2NvcmRpbmdseS4NCg0KLSBUaGlzIGhhbmRsZXIgaXMgYWxtb3N0 IDIwMCBsaW5lcyBvZiBjb2RlIGxvbmcsIGl0IGNvdWxkIGJlIHNwbGl0dGVkIGluDQogIHNtYWxs ZXIgcm91dGluZXM6DQoJKiBPbmUgZm9yIGhhbmRsaW5nIEZXVCBmcm9tIHRhZw0KCSogT25lIGZv ciBoYW5kbGluZyBJL08gZXJyb3JzDQoJKiBPbmUgZm9yIGFjdHVhbGx5IHByb2Nlc3NpbmcgdGhl IHJlc3BvbnNlDQpPay4gDQpJIHdpbGwgc3BsaXQgdGhlIGhhbmRsZXIgdG8gbWFrZSBpdCBtb3Jl IG1vZHVsYXIuDQoNCj4gK3N0YXRpYyBzdHJ1Y3QgbmZjX2RpZ2l0YWxfb3BzIHN0OTVoZl9uZmNf ZGlnaXRhbF9vcHMgPSB7DQo+ICsJLmluX2NvbmZpZ3VyZV9odyA9IHN0OTVoZl9pbl9jb25maWd1 cmVfaHcsDQo+ICsJLmluX3NlbmRfY21kID0gc3Q5NWhmX2luX3NlbmRfY21kLA0KPiArDQo+ICsJ LnRnX2xpc3RlbiA9IHN0OTVoZl90Z19saXN0ZW4sDQo+ICsJLnRnX2NvbmZpZ3VyZV9odyA9IHN0 OTVoZl90Z19jb25maWd1cmVfaHcsDQo+ICsJLnRnX3NlbmRfY21kID0gc3Q5NWhmX3RnX3NlbmRf Y21kLA0KPiArCS50Z19nZXRfcmZfdGVjaCA9IHN0OTVoZl90Z19nZXRfcmZfdGVjaCwNCj4gKw0K PiArCS5zd2l0Y2hfcmYgPSBzdDk1aGZfc3dpdGNoX3JmLA0KPiArCS5hYm9ydF9jbWQgPSBzdDk1 aGZfYWJvcnRfY21kLA0KQWxsIHRoZSBhYm92ZSBvcHMgY2FuIGJlIHN0YXRpYy4NCg0KT2suDQoN Cj4gK3N0YXRpYyBpbnQgc3Q5NWhmX3Byb2JlKHN0cnVjdCBzcGlfZGV2aWNlICpuZmNfc3BpX2Rl dikgew0KPiArCWludCByZXQ7DQo+ICsNCj4gKwlzdHJ1Y3Qgc3Q5NWhmX2NvbnRleHQgKnN0OTVj b250ZXh0Ow0KPiArCXN0cnVjdCBzcGlfY29udGV4dCAqc3BpY29udGV4dDsNCj4gKwlzdHJ1Y3Qg ZGV2aWNlX25vZGUgKm5wID0gbmZjX3NwaV9kZXYtPmRldi5vZl9ub2RlOw0KPiArDQo+ICsJcHJf aW5mbygiU1QgU1BJIFNMQVZFIERSSVZFUiAoU1Q5NUhGIFIvVyAxNDQ0M0EvQikgUFJPQkUgQ0FM TEVEXG4iKTsNCj4gKw0KPiArCXN0OTVjb250ZXh0ID0gZGV2bV9remFsbG9jKCZuZmNfc3BpX2Rl di0+ZGV2LA0KPiArCQkJCSAgIHNpemVvZihzdHJ1Y3Qgc3Q5NWhmX2NvbnRleHQpLA0KPiArCQkJ CSAgIEdGUF9LRVJORUwpOw0KPiArCWlmICghc3Q5NWNvbnRleHQpDQo+ICsJCXJldHVybiAtRU5P TUVNOw0KPiArDQo+ICsJc3BpY29udGV4dCA9ICZzdDk1Y29udGV4dC0+c3BpY29udGV4dDsNCj4g Kw0KPiArCXNwaWNvbnRleHQtPnNwaWRldiA9IG5mY19zcGlfZGV2Ow0KPiArDQo+ICsJc3Q5NWNv bnRleHQtPmZ3aSA9IA0KPiArY21kX2FycmF5W0lTTzE0NDQzQV9QUk9UT0NPTF9TRUxFQ1RdLmNt ZF9wYXJhbXNbMl07DQo+ICsNCj4gKwlpZiAob2ZfZ2V0X3Byb3BlcnR5KG5wLCAic3Q5NWhmdmlu LXN1cHBseSIsIE5VTEwpKSB7DQpQbGVhc2UgdXNlIGRldmljZV9wcm9wZXJ0eV9wcmVzZW50IHRv IGJlIGZpcm13YXJlIEFQSSBhZ25vc3RpYy4NCg0KT2suDQoNClRoYW5rcyEhDQpCZXN0IFJlZ2Fy ZHMsDQpTaGlraGENCg== ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support 2015-10-22 6:24 ` Samuel Ortiz 2015-10-26 5:57 ` Shikha SINGH @ 2015-11-06 9:13 ` Shikha SINGH 1 sibling, 0 replies; 7+ messages in thread From: Shikha SINGH @ 2015-11-06 9:13 UTC (permalink / raw) To: Samuel Ortiz Cc: aloisio.almeida@openbossa.org, lauro.venancio@openbossa.org, linux-wireless@vger.kernel.org, linux-nfc@lists.01.org, Raunaque Mujeeb QUAISER, Manoj KUMAR, Sylvain FIDELIS, Patrick SOHN SGVsbG8gU2FtdWVsLA0KICAgICAgICBUaGlzIG1haWwgaXMgaW4gcmVmZXJlbmNlIG9mIHlvdXIg YmVsb3cgZmVlZGJhY2suDQoNCj5EbyB5b3UgcmVhbGx5IG5lZWQgYSBzcGVjaWZpYyBJUlEgaGFu ZGxlciBmb3IgdGhhdCA/IENhbid0IHlvdSBkbyBpdCBmcm9tIHRoZQ0KPnRocmVhZGVkIGludGVy cnVwdCBjb250ZXh0ID8NCg0KQWZ0ZXIgc29tZSBleHBlcmltZW50cyBhdCBvdXIgZW5kLCB3ZSBm b3VuZCB0aGF0IHdlIGFyZSBub3QgYWJsZSB0byByZW1vdmUgc21hbGwgSVNSIChoYXJkaXJxIGNv bnRleHQpIGZyb20gZHJpdmVyIGNvZGUuDQoNClJlYXNvbiA6IFRoZXJlIGFyZSBmZXcgY29tbWFu ZHMgb2Ygb3VyIE5GQyB0cmFuc2NlaXZlciAodGhlIG9uZXMgdGhhdCBkbyBub3QgaW50ZXJhY3Qg b3IgZGF0YSBleGNoYW5nZSB3aXRoIHRoZSB0YWcpLCB3ZSB3YW50IHRvIGNvbXBsZXRlIHN5bmNo cm9ub3VzbHkuIFRoaXMgaXMgYWxzbyBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIG92ZXJseWluZyBk aWdpdGFsIGZyYW1ld29yayBleHBlY3RhdGlvbnMgKGZvciBleC4gaW1wbGVtZW50YXRpb24gb2Yg aW5fY29uZmlndXJlX2h3KCkgb3ApLiBGb3IgdGhhdCB3ZSB1c2UgdGhlIGNvbXBsZXRpb24gc3Ry dWN0dXJlIG9mIExpbnV4IEtlcm5lbCAoYXMgc3VnZ2VzdGVkIGJ5IHlvdSkgYW5kIHdhaXRpbmcg Zm9yIHRoZSBjb21wbGV0aW9uIHVzaW5nIHdhaXRfZm9yX2NvbXBsZXRpb25fdGltZW91dCgpIGlu IHRoZSByZXF1ZXN0aW5nIHRocmVhZC4gVGhlIGNvbXBsZXRpb24gaXMgZG9uZSBmcm9tIHRoZSBj b3JyZXNwb25kaW5nIGludGVycnVwdCBoYW5kbGVyLg0KICAgICAgICBJZiB3ZSB1c2UgdGhyZWFk ZWQgaW50ZXJydXB0IGhhbmRsZXIgZm9yIHRoZSBzYW1lLCBpdCBpcyBpbnRyb2R1Y2luZyB1bi1z dGFiaWxpdHkgaW4gdGhlIHN5c3RlbS4gRGVwZW5kaW5nIG9uIHdoZW4gdGhyZWFkZWQgSVNSIGlz IGdldCBzY2hlZHVsZWQgYnkgdGhlIHNjaGVkdWxlciwgc29tZXRpbWVzIGNvbXBsZXRpb24gdGFr ZSBsZXNzIHRpbWUgYW5kIHNvbWUgdGltZSBpdCB0YWtlcyBsb25nIHRpbWUgdG8gY29tcGxldGUu IEluIHRoaXMgc2l0dWF0aW9uIGl0IGlzIGJlY29taW5nIGRpZmZpY3VsdCB0byBwcm92aWRlIGEg Z3VhcmFudGVlZCAoYW5kIGhhcmQgY29kZWQpIHZhbHVlIG9mIHRpbWVvdXQgaW4gd2hpY2ggY29t cGxldGlvbiBjYW4gYmUgZ3VhcmFudGVlZCB0byB0aGUgcmVxdWVzdGluZyB0aHJlYWQuIE90aGVy IHdheSBjb3VsZCBiZSB0byB3YWl0IGZvciBjb21wbGV0aW9uIHdpdGhvdXQgdGltZW91dCBidXQg aW4gdGhhdCBjYXNlIHdlIHdvdWxkIG5vdCBiZSBhYmxlIHRvIGNhdGNoIGhhcmR3YXJlIGVycm9y cyAocmVhbCB0aW1lb3V0IGhhcHBlbnMgZHVlIHRvIGZhdWx0eSBoYXJkd2FyZSksIHNvIHRoZXJl IGlzIHJpc2sgb2YgaGFuZyBpbiB0aGUgc3lzdGVtLg0KICAgICAgICBUaHVzIHdlIHdpbGwgYmUg dXNpbmcgaGFyZGlycSBjb250ZXh0IHRvIGRvIHRoZSBjb21wbGV0aW9uIHRvIGhhdmUgYSBzdGFi bGUgYW5kIG1vcmUgZGV0ZXJtaW5pc3RpYyBiZWhhdmlvciBhcyBjb2RlIGluIGhhcmRpcnEgY29u dGV4dCBndWFyYW50ZWVkIHRvIHJ1biBzb29uZXIgdGhhbiBpbiB0aHJlYWQgY29udGV4dC4gSW4g dGhpcyB3YXkgd2UgY2FuIHNldCBhIGZpeGVkICh1cHBlciBib3VuZCkgdGltZW91dCB2YWx1ZSBp biB3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoKSBpbiB0aGUgcmVxdWVzdGluZyB0aHJlYWQu IEluIHRoYXQgd2F5IGlmIHRpbWVvdXQgaGFwcGVucyB3ZSBhcmUgY29uZmlkZW50IHRoYXQgaXQg aXMgZHVlIHRvIGhhcmR3YXJlIGZhaWx1cmUgISENCk5vdGUgdGhhdCB0aGUgcmVzdCBvZiB0aGUg Y29tbWFuZHMgcmVzcG9uc2UgZnJvbSBORkMgIHRyYW5zY2VpdmVyIHdpbGwgYmUgaGFuZGxlZCBi eSB0aGUgdGhyZWFkZWQgSVNSLiBUaGlzIGluY2x1ZGUgYWxsIHRoZSBleGNoYW5nZXMgb2YgZnJh bWVzIGJldHdlZW4gdGhlIHRhZyBhbmQgdGhlIHRyYW5zY2VpdmVyLiBTbyBidWxrIHByb2Nlc3Np bmcgKGFuZCBoZW5jZSBubyB0aW1lIGNyaXRpY2FsIG9yIHN5bmNocm9ub3VzIGNvbXBsZXRpb24g cmVxdWlyZW1lbnQpIHdpbGwgYmUgcGFydCBvZiB0aGUgdGhyZWFkZWQgSVNSLiBJbiBzdWNoIGNh c2VzIHRoZSBoYXJkaXJxIGNvbnRleHQgd2lsbCBtZXJlbHkgd2FrZS11cCB0aGUgSVNSIHRocmVh ZCBhbmQgZXhpdC4NCg0KUmVzdCBvZiB5b3VyIGZlZWRiYWNrcyBhcmUgYWNjb21tb2RhdGVkIGFu ZCBJIGFtIGdvaW5nIHRvIHJlbGVhc2UgbmV3IHZlcnNpb24odjIpIG9mIGRyaXZlciBhY2NvcmRp bmdseS4NCg0KVGhhbmtzICYgUmVnYXJkcywNClNoaWtoYQ0KDQoNCj4tLS0tLU9yaWdpbmFsIE1l c3NhZ2UtLS0tLQ0KPkZyb206IFNoaWtoYSBTSU5HSA0KPlNlbnQ6IE1vbmRheSwgT2N0b2JlciAy NiwgMjAxNSAxMToyOCBBTQ0KPlRvOiAnU2FtdWVsIE9ydGl6Jw0KPkNjOiBhbG9pc2lvLmFsbWVp ZGFAb3BlbmJvc3NhLm9yZzsgbGF1cm8udmVuYW5jaW9Ab3BlbmJvc3NhLm9yZzsgbGludXgtDQo+ d2lyZWxlc3NAdmdlci5rZXJuZWwub3JnOyBsaW51eC1uZmNAbGlzdHMuMDEub3JnOyBSYXVuYXF1 ZSBNdWplZWIgUVVBSVNFUjsNCj5NYW5vaiBLVU1BUjsgU3lsdmFpbiBGSURFTElTOyBQYXRyaWNr IFNPSE4NCj5TdWJqZWN0OiBSRTogW1tsaW51eC1uZmNdIFBBVENIIHYxLjAgMi8zXSBkcml2ZXI6 IG5mYzogc3Q5NWhmOiBTVCBORkMgVHJhbnNjZWl2ZXINCj5zdXBwb3J0DQo+DQo+DQo+SGkgU2Ft dWVsLA0KPiAgICAgICBUaGFua3MgZm9yIHlvdXIgcmV2aWV3Lg0KPg0KPg0KPk9uIFNhdCwgU2Vw IDEyLCAyMDE1IGF0IDAzOjIxOjM0QU0gLTA0MDAsIFNoaWtoYSBTaW5naCB3cm90ZToNCj4+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL25mYy9zdDk1aGYvTWFrZWZpbGUgYi9kcml2ZXJzL25mYy9zdDk1 aGYvTWFrZWZpbGUNCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0IGluZGV4IDAwMDAwMDAuLjJkOGY4 ZjMNCj4+IC0tLSAvZGV2L251bGwNCj4+ICsrKyBiL2RyaXZlcnMvbmZjL3N0OTVoZi9NYWtlZmls ZQ0KPj4gQEAgLTAsMCArMSw2IEBADQo+PiArIw0KPj4gKyMgTWFrZWZpbGUgZm9yIFNUTWljcm9l bGVjdHJvbmljcyBORkMgdHJhbnNjZWl2ZXIgU1Q5NUhGICMgIw0KPj4gKw0KPj4gK29iai0kKENP TkZJR19ORkNfU1Q5NUhGKSAgICArPSBzdF90cmFuc2NlaXZlci5vDQo+V2Ugc2hvdWxkIGJlIG1v cmUgc3BlY2lmaWMgYW5kIGNhbGwgaXQgc3RfbmZjX3RyYW5zY2VpdmVyIGZvciBleGFtcGxlLg0K Pg0KPk9rLg0KPg0KPj4gKy8qIEZ1bmN0aW9uIHRvIHNlbmQgdXNlciBwcm92aWRlZCBidWZmZXIg dG8gU1Q5NUhGIHRocm91Z2ggU1BJICovIGludA0KPj4gK3NwaV9zZW5kX3RvX3N0OTVoZihzdHJ1 Y3Qgc3BpX2NvbnRleHQgKnNwaWNvbnRleHQsDQo+PiArICAgICAgICAgICAgICAgICAgIHVuc2ln bmVkIGNoYXIgKmJ1ZmZlcnR4LCBpbnQgZGF0YWxlbiwNCj4+ICsgICAgICAgICAgICAgICAgICAg ZW51bSByZXFfdHlwZSByZXF0eXBlKQ0KPlRvIGJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgcmVzdCBv ZiB5b3VyIEFQSSwgdGhpcyBvbmUgc2hvdWxkIGJlIGNhbGxlZA0KPnN0OTVoZl9zcGlfc2VuZCgp LiBJdCBvYnZpb3VzbHkgaW1wbGllcyB0aGF0IGl0IGlzIHNlbmRpbmcgcGFja2V0cyB0byB0aGUN Cj50cmFuc2NlaXZlci4NCj4NCj5Pay4NCj4NCj4+ICt7DQo+PiArICAgIHN0cnVjdCBzcGlfbWVz c2FnZSBtOw0KPj4gKyAgICBpbnQgcmVzdWx0ID0gMDsNCj4+ICsgICAgc3RydWN0IHNwaV9kZXZp Y2UgKnNwaWRldiA9IHNwaWNvbnRleHQtPnNwaWRldjsNCj4+ICsgICAgc3RydWN0IHNwaV90cmFu c2ZlciB0eF90cmFuc2ZlciA9IHsNCj4+ICsgICAgICAgICAgICAucnhfYnVmID0gTlVMTCwNCj4+ ICsgICAgICAgICAgICAudHhfYnVmID0gYnVmZmVydHgsDQo+PiArICAgICAgICAgICAgLmxlbiA9 IGRhdGFsZW4sDQo+PiArICAgICAgICAgICAgLmNzX2NoYW5nZSA9IDAsDQo+PiArICAgICAgICAg ICAgLmJpdHNfcGVyX3dvcmQgPSAwLA0KPj4gKyAgICAgICAgICAgIC5kZWxheV91c2VjcyA9IDAs DQo+PiArICAgICAgICAgICAgLnNwZWVkX2h6ID0gMCwNCj4+ICsgICAgfTsNCj5Zb3UgZG9uJ3Qg bmVlZCB0byBleHBsaWNpdGVseSBzZXQgdGhvc2UgZmllbGRzIHRvIE5VTEwgb3IgMCwgdGhpcyBv bmUgY291bGQgYmUNCj5zaW1wbGlmaWVkIHRvOg0KPg0KPnN0cnVjdCBzcGlfdHJhbnNmZXIgdCA9 IHsgLnR4X2J1ZiA9IGJ1ZmZlcnR4LCAubGVuID0gZGF0YWxlbiwgfTsNCj4NCj5Pay4NCj4NCj4+ ICsgICAgc3BpY29udGV4dC0+cmVwbHlfZnJvbV9zdDk1ID0gMDsNCj4+ICsNCj4+ICsgICAgaWYg KHJlcXR5cGUgPT0gU1lOQykNCj4+ICsgICAgICAgICAgICBzcGljb250ZXh0LT5yZXFfaXNzeW5j ID0gdHJ1ZTsNCj4+ICsgICAgZWxzZQ0KPj4gKyAgICAgICAgICAgIHNwaWNvbnRleHQtPnJlcV9p c3N5bmMgPSBmYWxzZTsNCj4+ICsNCj4+ICsgICAgc3BpX21lc3NhZ2VfaW5pdCgmbSk7DQo+PiAr ICAgIHNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0eF90cmFuc2ZlciwgJm0pOw0KPj4gKw0KPj4gKyAg ICByZXN1bHQgPSBzcGlfc3luYyhzcGlkZXYsICZtKTsNCj4+ICsgICAgaWYgKHJlc3VsdCkgew0K Pj4gKyAgICAgICAgICAgIGRldl9lcnIoJnNwaWRldi0+ZGV2LA0KPj4gKyAgICAgICAgICAgICAg ICAgICAgImVycm9yOiBzZW5kaW5nIGNtZCB0byBzdDk1aGYgdXNpbmcgU1BJXG4iKTsNCj4+ICsg ICAgICAgICAgICByZXR1cm4gcmVzdWx0Ow0KPj4gKyAgICB9DQo+PiArDQo+PiArICAgIGlmIChy ZXF0eXBlID09IEFTWU5DKSB7IC8qIHJldHVybiBmb3IgYXN5bmNocm9ub3VzIG9yIG5vLXdhaXQg Y2FzZSAqLw0KPj4gKyAgICAgICAgICAgIHJldHVybiAwOw0KPj4gKyAgICB9DQo+PiArDQo+PiAr ICAgIGRvIHsNCj4+ICsgICAgICAgICAgICByZXN1bHQgPSB3YWl0X2V2ZW50X2ludGVycnVwdGli bGVfdGltZW91dCgNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BpY29udGV4dC0+ c3Q5NXdhaXRfcXVldWUsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwaWNvbnRl eHQtPnJlcGx5X2Zyb21fc3Q5NSA9PSAxLA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAxMDAwKTsNCj4+ICsgICAgfSB3aGlsZSAocmVzdWx0IDwgMCk7DQo+SWYgcmVzdWx0IGlzIDwg MCBpdCBtZWFucyB5b3VyIHRyYW5zZmVyIGdvdCBpbnRlcnJ1cHRlZCBieSBhIHNpZ25hbCwgdGhl cmUgaXMgbm8NCj5wb2ludCBpbiBsb29waW5nIGFyb3VuZCByZXN1bHQuIFlvdSBtYXkganVzdCB3 YW50IHRvIHJldHVybiByZXN1bHQgaW4gdGhhdCBjYXNlLg0KPg0KPkFncmVlLiBJIHdpbGwgY29y cmVjdCBpbiBuZXh0IHZlcnNpb24uDQo+DQo+QSBjb3VwbGUgbW9yZSBjb21tZW50cyBoZXJlOg0K Pi0gQSBjb21wbGV0aW9uIGlzIHByb2JhYmx5IGVub3VnaCBmb3Igd2hhdCB5b3UncmUgdHJ5aW5n IHRvIGFjaGlldmUuDQo+DQo+WWVzLiBJIHdpbGwgbWFrZSBjaGFuZ2VzIGFjY29yZGluZ2x5Lg0K Pg0KPi0gVGhpcyBpcyByYWN5OiBJZiB5b3UgaGF2ZSAyIHRocmVhZHMgY2FsbGluZyBzcGlfc2Vu ZF90b19zdDk1aGYoKSBhdA0KPiAgdGhlIHNhbWUgdGltZSB0aGV5IG1heSBlbmQgdXAgd2FpdGlu ZyBvbiB0aGUgd2FpdHF1ZXVlIGF0IHRoZSBzYW1lDQo+ICB0aW1lIGFzIHdlbGwuIFRoZSBmaXJz dCBpbnRlcnJ1cHQgdGhhdCBjb21lcyB3aWxsIHdha2UgYm90aCBhdCB0aGUNCj4gIHNhbWUgdGlt ZSBhbHRob3VnaCBpdCBzaG91bGQgbm90Lg0KPiAgSW4gb3JkZXIgdG8gYXZvaWQgdGhhdCByYWNl LCB5b3UgbmVlZCB0byBzeW5jaHJvbml6ZSB0aGUgY2FsbHMgdG8NCj4gIHNwaV9zeW5jIHdpdGgg ZS5nLiBhIG11dGV4IHNvIHRoYXQgeW91IGRvbid0IGlzc3VlIGFuIHNwaV9zeW5jIHdoaWxlDQo+ ICBzb21lb25lIGlzIGFscmVhZHkgb24gdGhlIHdhaXRxdWV1ZSBvciBzbGVlcGluZyBmb3IgY29t cGxldGlvbi4NCj4NCj5Pay4gQWx0aG91Z2ggYXQgcHJlc2VudCB0aGVyZSBpcyBubyBzaXR1YXRp b24gd2hlcmUgc3BpX3NlbmRfdG9fc3Q5NWhmKCkgY2FuIGJlDQo+Y2FsbGVkIHNpbXVsdGFuZW91 c2x5IGJ1dCBJIHdpbGwgYWNjb21tb2RhdGUgeW91ciBzdWdnZXN0aW9uIHRvIGhhdmUgYSBzYWZl DQo+Y29kZS4NCj4NCj4+ICsNCj4+ICsgICAgaWYgKHJlc3VsdCA9PSAwKSB7DQo+PiArICAgICAg ICAgICAgZGV2X2Vycigmc3BpZGV2LT5kZXYsICJlcnJvcjogcmVzcG9uc2Ugbm90IHJlYWR5IHRp bWVvdXRcbiIpOw0KPj4gKyAgICAgICAgICAgIHJldHVybiAtRVRJTUVET1VUOw0KPj4gKyAgICB9 DQo+PiArDQo+PiArICAgIGlmIChyZXN1bHQgPiAwKQ0KPj4gKyAgICAgICAgICAgIHJlc3VsdCA9 IDA7DQo+PiArDQo+PiArICAgIHJldHVybiByZXN1bHQ7DQo+PiArfQ0KPj4gK0VYUE9SVF9TWU1C T0xfR1BMKHNwaV9zZW5kX3RvX3N0OTVoZik7DQo+PiArDQo+PiArLyogRnVuY3Rpb24gdG8gUmVj ZWl2ZSBjb21tYW5kIFJlc3BvbnNlICovIGludA0KPj4gK3NwaV9yZWNlaXZlX3Jlc3BvbnNlKHN0 cnVjdCBzcGlfY29udGV4dCAqc3BpY29udGV4dCwNCj4+ICsgICAgICAgICAgICAgICAgICAgICB1 bnNpZ25lZCBjaGFyICpyZWNlaXZlYnVmZiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICBpbnQg KmxlbikNCj4yIHRoaW5nczoNCj4NCj4tIExldCdzIGNhbGwgdGhhdCBvbmUgc3Q5NWhmX3NwaV9y ZWN2X3Jlc3BvbnNlKCkNCj4NCj5Pay4NCj4NCj4tIEl0IHR5cGljYWxseSBzaG91bGQgcmV0dXJu IHRoZSBudW1iZXIgb2YgcmVhZCBieXRlcywgaW5zdGVhZCBvZg0KPiAgcGFzc2luZyBhIGxlbiBw b2ludGVyIHRvIHRoZSBhcmd1bWVudCBsaXN0Lg0KPg0KPk9rLg0KPg0KPg0KPj4gK3sNCj4+ICsg ICAgc3RydWN0IHNwaV90cmFuc2ZlciB0eF90YWtlcmVzcG9uc2UxOw0KPj4gKyAgICBzdHJ1Y3Qg c3BpX3RyYW5zZmVyIHR4X3Rha2VyZXNwb25zZTI7DQo+PiArICAgIHN0cnVjdCBzcGlfdHJhbnNm ZXIgdHhfdGFrZWRhdGE7DQo+PiArICAgIHN0cnVjdCBzcGlfbWVzc2FnZSBtOw0KPj4gKyAgICB1 bnNpZ25lZCBjaGFyIHJlYWRkYXRhX2NtZCA9IFNUOTVIRl9DT01NQU5EX1JFQ0VJVkU7DQo+PiAr ICAgIGludCByZXQgPSAwOw0KPj4gKw0KPj4gKyAgICBzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpZGV2 ID0gc3BpY29udGV4dC0+c3BpZGV2Ow0KPj4gKw0KPj4gKyAgICAqbGVuID0gMDsNCj4+ICsNCj4+ ICsgICAgbWVtc2V0KCZ0eF90YWtlcmVzcG9uc2UxLCAweDAsIHNpemVvZihzdHJ1Y3Qgc3BpX3Ry YW5zZmVyKSk7DQo+PiArICAgIG1lbXNldCgmdHhfdGFrZXJlc3BvbnNlMiwgMHgwLCBzaXplb2Yo c3RydWN0IHNwaV90cmFuc2ZlcikpOw0KPj4gKyAgICBtZW1zZXQoJnR4X3Rha2VkYXRhLCAweDAs IHNpemVvZihzdHJ1Y3Qgc3BpX3RyYW5zZmVyKSk7DQo+PiArDQo+PiArICAgIHR4X3Rha2VyZXNw b25zZTEudHhfYnVmID0gJnJlYWRkYXRhX2NtZDsNCj4+ICsgICAgdHhfdGFrZXJlc3BvbnNlMS5s ZW4gPSAxOw0KPj4gKw0KPj4gKyAgICB0eF90YWtlcmVzcG9uc2UyLnJ4X2J1ZiA9IHJlY2VpdmVi dWZmOw0KPj4gKyAgICAvKiAxIGJ5dGUgIFJlc3BvbnNlIGNvZGUgKyAxIGJ5dGUgIGxlbmd0aCBv ZiBkYXRhICovDQo+PiArICAgIHR4X3Rha2VyZXNwb25zZTIubGVuID0gMjsNCj4+ICsgICAgLyog RG9udCBhbGxvdyB0byBtYWtlIGNoaXBzZWxlY3QgaGlnaCAqLw0KPj4gKyAgICB0eF90YWtlcmVz cG9uc2UyLmNzX2NoYW5nZSA9IDE7DQo+PiArDQo+PiArICAgIHNwaV9tZXNzYWdlX2luaXQoJm0p Ow0KPj4gKyAgICBzcGlfbWVzc2FnZV9hZGRfdGFpbCgmdHhfdGFrZXJlc3BvbnNlMSwgJm0pOw0K Pj4gKyAgICBzcGlfbWVzc2FnZV9hZGRfdGFpbCgmdHhfdGFrZXJlc3BvbnNlMiwgJm0pOw0KPg0K PlNvIHRoaXMgd2hvbGUgYmxvY2sgb2YgY29kZSBjb3VsZCBiZSBzaW1wbGlmaWVkIHRvOg0KPg0K PnN0cnVjdCBzcGlfdHJhbnNmZXIgdFsyXSA9IHsgeyAudHhfYnVmID0gJnJlYWRkYXRhX2NtZCwg LmxlbiA9IDEsIH0sDQo+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IC5yeF9idWYgPSBy ZWNlaXZlX2J1ZmYsICAubGVuID0gMiAsIC5jc19jaGFuZ2UgPSAxLCB9LCB9Ow0KPg0KPnNwaV9t ZXNzYWdlX2luaXQoJm0pOw0KPnNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0WzBdLCAmbSk7DQo+c3Bp X21lc3NhZ2VfYWRkX3RhaWwoJnRbMV0sICZtKTsNCj4NCj5Pay4NCj4NCj4+ICsgICAgcmV0ID0g c3BpX3N5bmMoc3BpZGV2LCAmbSk7DQo+PiArICAgIGlmIChyZXQpDQo+PiArICAgICAgICAgICAg cmV0dXJuIHJldDsNCj4+ICsNCj4+ICsgICAgLyogMiBieXRlcyBhcmUgYWxyZWFkeSByZWFkICov DQo+PiArICAgICpsZW4gPSAyOw0KPj4gKw0KPj4gKyAgICAvKnN1cHBvcnQgb2YgbG9uZyBmcmFt ZSovDQo+Tml0cGljazogUGxlYXNlIGFkZCBhIHNwYWNlIGFmdGVyIC8qIGFuZCBiZWZvcmUgKi8N Cj4NCj5Pay4NCj4NCj4+ICsgICAgaWYgKHJlY2VpdmVidWZmWzBdICYgMHg2MCkNCj4+ICsgICAg ICAgICAgICAqbGVuICs9ICgoKHJlY2VpdmVidWZmWzBdICYgMHg2MCkgPj4gNSkgPDwgOCkgfCBy ZWNlaXZlYnVmZlsxXTsNCj4+ICsgICAgZWxzZQ0KPj4gKyAgICAgICAgICAgICpsZW4gKz0gcmVj ZWl2ZWJ1ZmZbMV07DQo+PiArDQo+PiArICAgIC8qIE5vdyBtYWtlIGEgdHJhbnNmZXIgdG8gdGFr ZSBvbmx5IHJlbGV2YW50IGRhdGEgKi8NCj4+ICsgICAgdHhfdGFrZWRhdGEucnhfYnVmID0gJnJl Y2VpdmVidWZmWzJdOw0KPj4gKyAgICB0eF90YWtlZGF0YS5sZW4gPSAoKmxlbikgLSAyOw0KPj4g KyAgICB0eF90YWtlZGF0YS5jc19jaGFuZ2UgPSAwOw0KPj4gKw0KPj4gKyAgICBzcGlfbWVzc2Fn ZV9pbml0KCZtKTsNCj4+ICsgICAgc3BpX21lc3NhZ2VfYWRkX3RhaWwoJnR4X3Rha2VkYXRhLCAm bSk7DQo+PiArDQo+PiArICAgIHJldHVybiBzcGlfc3luYyhzcGlkZXYsICZtKTsNCj4+ICt9DQo+ PiArRVhQT1JUX1NZTUJPTF9HUEwoc3BpX3JlY2VpdmVfcmVzcG9uc2UpOw0KPj4gKw0KPj4gK2lu dCBzcGlfcmVjZWl2ZV9lY2hvX3Jlc3BvbnNlKHN0cnVjdCBzcGlfY29udGV4dCAqc3BpY29udGV4 dCwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnJlY2VpdmVi dWZmKQ0KPlNpbWlsYXIgY29tbWVudCwgcGxlYXNlIGNhbGwgaXQgc3Q5NWhmX3JlY3ZfZWNobygp Lg0KPg0KPk9rLg0KPg0KPj4gK3sNCj4+ICsgICAgc3RydWN0IHNwaV90cmFuc2ZlciB0eF90YWtl cmVzcG9uc2UxOw0KPj4gKyAgICBzdHJ1Y3Qgc3BpX3RyYW5zZmVyIHR4X3Rha2VkYXRhOw0KPj4g KyAgICBzdHJ1Y3Qgc3BpX21lc3NhZ2UgbTsNCj4+ICsgICAgdW5zaWduZWQgY2hhciByZWFkZGF0 YV9jbWQgPSBTVDk1SEZfQ09NTUFORF9SRUNFSVZFOw0KPj4gKyAgICBzdHJ1Y3Qgc3BpX2Rldmlj ZSAqc3BpZGV2ID0gc3BpY29udGV4dC0+c3BpZGV2Ow0KPj4gKw0KPj4gKyAgICBtZW1zZXQoJnR4 X3Rha2VyZXNwb25zZTEsIDB4MCwgc2l6ZW9mKHN0cnVjdCBzcGlfdHJhbnNmZXIpKTsNCj4+ICsg ICAgbWVtc2V0KCZ0eF90YWtlZGF0YSwgMHgwLCBzaXplb2Yoc3RydWN0IHNwaV90cmFuc2Zlcikp Ow0KPj4gKw0KPj4gKyAgICB0eF90YWtlcmVzcG9uc2UxLnR4X2J1ZiA9ICZyZWFkZGF0YV9jbWQ7 DQo+PiArICAgIHR4X3Rha2VyZXNwb25zZTEubGVuID0gMTsNCj4+ICsgICAgdHhfdGFrZXJlc3Bv bnNlMS5yeF9idWYgPSBOVUxMOw0KPj4gKw0KPj4gKyAgICB0eF90YWtlZGF0YS5yeF9idWYgPSBy ZWNlaXZlYnVmZjsNCj4+ICsgICAgdHhfdGFrZWRhdGEudHhfYnVmID0gTlVMTDsNCj4+ICsgICAg dHhfdGFrZWRhdGEubGVuID0gMTsNCj4+ICsNCj4+ICsgICAgc3BpX21lc3NhZ2VfaW5pdCgmbSk7 DQo+PiArICAgIHNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0eF90YWtlcmVzcG9uc2UxLCAmbSk7DQo+ PiArICAgIHNwaV9tZXNzYWdlX2FkZF90YWlsKCZ0eF90YWtlZGF0YSwgJm0pOw0KPlNpbWlsYXIg Y29tbWVudCBhcyB3ZWxsLCB0aGlzIGNhbiBiZSBzaW1wbGlmaWVkIGFzIGRlc2NyaWJlZCBhYm92 ZS4NCj4NCj5Pay4NCj4NCj4+ICsgICAgcmV0dXJuIHNwaV9zeW5jKHNwaWRldiwgJm0pOw0KPj4g K30NCj4+ICtFWFBPUlRfU1lNQk9MX0dQTChzcGlfcmVjZWl2ZV9lY2hvX3Jlc3BvbnNlKTsNCj4+ IGRpZmYgLS1naXQgYS9kcml2ZXJzL25mYy9zdDk1aGYvc3BpLmggYi9kcml2ZXJzL25mYy9zdDk1 aGYvc3BpLmggbmV3DQo+PiBmaWxlIG1vZGUgMTAwNjQ0IGluZGV4IDAwMDAwMDAuLmFhM2VlYTBk DQo+PiAtLS0gL2Rldi9udWxsDQo+PiArKysgYi9kcml2ZXJzL25mYy9zdDk1aGYvc3BpLmgNCj4+ IEBAIC0wLDAgKzEsNDUgQEANCj4+ICsgLyoNCj4+ICsgKg0KPj4gKyAtLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KPj4g KyAtLS0tLS0tLS0NCj4+ICsgKiBkcml2ZXJzL25mYy9zdDk1aGYvc3BpLmggZnVuY3Rpb25zIGRl Y2xhcmF0aW9ucyBmb3IgU1BJDQo+PiArIGNvbW11bmljYXRpb24NCj4+ICsgKg0KPj4gKyAtLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLQ0KPj4gKyAtLS0tLS0tLS0NCj4+ICsgKg0KPj4gKyAqIENvcHlyaWdodCAoQykgMjAx NSBTVE1pY3JvZWxlY3Ryb25pY3Mg4oCTIEFsbCBSaWdodHMgUmVzZXJ2ZWQNCj4+ICsgKiBBdXRo b3I6IFNoaWtoYSBTaW5naCA8c2hpa2hhLnNpbmdoQHN0LmNvbT4NCj4+ICsgKg0KPj4gKyAqIE1h eSBiZSBjb3BpZWQgb3IgbW9kaWZpZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJh bA0KPj4gKyBQdWJsaWMNCj4+ICsgKiBMaWNlbnNlIFZlcnNpb24gMi4wIG9ubHkuIFNlZSBsaW51 eC9DT1BZSU5HIGZvciBtb3JlIGluZm9ybWF0aW9uLg0KPj4gKyAqDQo+PiArIC0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t DQo+PiArIC0tLS0tLS0NCj4+ICsgKi8NCj4+ICsNCj4+ICsjaWZuZGVmIF9fTElOVVhfU1Q5NUhG X1NQSV9IDQo+PiArI2RlZmluZSBfX0xJTlVYX1NUOTVIRl9TUElfSA0KPj4gKw0KPj4gKyNpbmNs dWRlIDxsaW51eC9zcGkvc3BpLmg+DQo+PiArDQo+PiArc3RydWN0IHNwaV9jb250ZXh0IHsNCj5z dHJ1Y3Qgc3Q5NWhmX3NwaV9jb250ZXh0IHdvdWxkIGJlIG1vcmUgYXByb3ByaWF0ZS4NCj4NCj5P ay4NCj4NCj4+ICsgICAgaW50IHJlcGx5X2Zyb21fc3Q5NTsNCj4+ICsgICAgd2FpdF9xdWV1ZV9o ZWFkX3Qgc3Q5NXdhaXRfcXVldWU7DQo+SSB0aGluayB0aG9zZSAyIGNhbiBlYXNpbHkgYmUgcmVw bGFjZWQgYnkgYSBzaW1wbGUgY29tcGxldGlvbiBzdHJ1Y3R1cmUuDQo+DQo+QWdyZWUuIEkgd2ls bCByZXBsYWNlIGl0IHdpdGggY29tcGxldGlvbiBzdHJ1Y3R1cmUgb2Yga2VybmVsLg0KPg0KPj4g K3N0YXRpYyBpcnFyZXR1cm5fdCBpcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICAqc3Q5NWhmY29u dGV4dCkgew0KPj4gKyAgICBzdHJ1Y3Qgc3Q5NWhmX2NvbnRleHQgKnN0Y29udGV4dCAgPQ0KPj4g KyAgICAgICAgICAgIChzdHJ1Y3Qgc3Q5NWhmX2NvbnRleHQgKilzdDk1aGZjb250ZXh0Ow0KPj4g Kw0KPj4gKyAgICBpZiAoc3Rjb250ZXh0LT5zcGljb250ZXh0LnJlcV9pc3N5bmMpIHsNCj4+ICsg ICAgICAgICAgICBzdGNvbnRleHQtPnNwaWNvbnRleHQucmVwbHlfZnJvbV9zdDk1ID0gMTsNCj4+ ICsgICAgICAgICAgICB3YWtlX3VwX2ludGVycnVwdGlibGUoJnN0Y29udGV4dC0+c3BpY29udGV4 dC5zdDk1d2FpdF9xdWV1ZSk7DQo+PiArICAgICAgICAgICAgcmV0dXJuIElSUV9IQU5ETEVEOw0K Pj4gKyAgICB9DQo+PiArDQo+PiArICAgIHJldHVybiBJUlFfV0FLRV9USFJFQUQ7DQo+PiArfQ0K PkRvIHlvdSByZWFsbHkgbmVlZCBhIHNwZWNpZmljIElSUSBoYW5kbGVyIGZvciB0aGF0ID8gQ2Fu J3QgeW91IGRvIGl0IGZyb20gdGhlDQo+dGhyZWFkZWQgaW50ZXJydXB0IGNvbnRleHQgPw0KPg0K PkN1cnJlbnRseSB3ZSBkb24ndCBuZWVkIHRvIHJ1biBhbnkgc3BlY2lmaWMgY29kZSBpbiBoYXJk IElSUSBjb250ZXh0IHNvIHllcyB3ZQ0KPmNhbiB1c2Ugc2luZ2xlIHRocmVhZGVkIGludGVycnVw dCBjb250ZXh0IGZvciBhbGwgY2FzZXMuDQo+SSB3aWxsIG1vZGlmeS4NCj4NCj4+ICtzdGF0aWMg aXJxcmV0dXJuX3QgaXJxX3RocmVhZF9oYW5kbGVyKGludCBpcnEsIHZvaWQgICpzdDk1aGZjb250 ZXh0KQ0KPj4gK3sNCj4+ICsgICAgaW50IHJlc3VsdDsNCj4+ICsgICAgaW50IHJlc19sZW47DQo+ PiArICAgIGludCBza2JfbGVuOw0KPj4gKyAgICBzdGF0aWMgYm9vbCB3dHg7DQo+PiArICAgIHN0 cnVjdCBwYXJhbV9saXN0IG5ld19wYXJhbXNbMV07DQo+PiArICAgIHN0cnVjdCBzdDk1aGZfY29u dGV4dCAqc3Rjb250ZXh0ICA9DQo+PiArICAgICAgICAgICAgKHN0cnVjdCBzdDk1aGZfY29udGV4 dCAqKXN0OTVoZmNvbnRleHQ7DQo+PiArICAgIHVuc2lnbmVkIGNoYXIgZXJyb3JfYnl0ZTsNCj4+ ICsgICAgc3RydWN0IGRldmljZSAqZGV2ID0gJnN0Y29udGV4dC0+bmZjZGV2LT5kZXY7DQo+PiAr ICAgIHN0cnVjdCBuZmNfZGlnaXRhbF9kZXYgKm5mY2RkZXYgPSBzdGNvbnRleHQtPmRkZXY7DQo+ PiArICAgIHVuc2lnbmVkIGNoYXIgdmFsX21tOw0KPj4gKw0KPj4gKyAgICBzdHJ1Y3Qgc3Q5NV9k aWdpdGFsX2NtZF9jb21wbGV0ZV9hcmcgKmNiX2FyZyA9DQo+PiArICAgICAgICAgICAgc3Rjb250 ZXh0LT5jb21wbGV0ZV9jYl9hcmc7DQo+PiArDQo+PiArICAgIGlmICghY2JfYXJnKSB7DQo+PiAr ICAgICAgICAgICAgZGV2X2VycihkZXYsICJjYl9hcmcgaXMgTlVMTCBpbiB0aHJlYWRlZCBJU1Jc biIpOw0KPj4gKyAgICAgICAgICAgIEJVRygpOw0KPj4gKyAgICB9DQo+PiArDQo+PiArICAgIHJl c3VsdCA9IHNwaV9yZWNlaXZlX3Jlc3BvbnNlKCZzdGNvbnRleHQtPnNwaWNvbnRleHQsDQo+PiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiX2FyZy0+c2tiX3Jlc3AtPmRhdGEs DQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZXNfbGVuKTsNCj4+ICsg ICAgaWYgKHJlc3VsdCkgew0KPj4gKyAgICAgICAgICAgIGRldl9lcnIoZGV2LCAicmVzIHJlY2Vp dmUgdGhyZWFkZWQgSVNSIGVyciA9IDB4JXhcbiIsIHJlc3VsdCk7DQo+PiArICAgICAgICAgICAg Z290byBlbmQ7DQo+PiArICAgIH0NCj4+ICsNCj4+ICsgICAgaWYgKCooKGNiX2FyZy0+c2tiX3Jl c3AtPmRhdGEpICsgMikgPT0gV1RYX1JFUV9GUk9NX1RBRykgew0KPj4gKyAgICAgICAgICAgIC8q IFJlcXVlc3QgZm9yIG5ldyBGV1QgZnJvbSB0YWcgKi8NCj5GV1QgPw0KPg0KPkZXVCBpcyBGcmFt ZSBXYWl0aW5nIFRpbWUuDQo+QWNjb3JkaW5nIHRvIElTTy1ERVAgcHJvdG9jb2wsIHRhZyBjYW4g c2VuZCB0aGUgcmVxdWVzdCB0byByZWFkZXIgZm9yIG5ldw0KPndhaXRpbmcgdGltZSB1c2luZyBX VFggcmVxdWVzdCAoV2FpdGluZyBUaW1lIGVYdGVuc2lvbikgd2hlbiB0YWcgbmVlZCBtb3JlDQo+ dGltZSBhdCBpdHMgZW5kIGZvciBwcm9jZXNzaW5nLg0KPkluIHRoaXMgc2l0dWF0aW9uLCBpbiBy ZXNwb25zZSBvZiBXVFggcmVxdWVzdCByZWFkZXIgaXMgYWxzbyByZXF1aXJlZCB0byBiZSByZS0N Cj5jb25maWd1cmVkIHRvIGluY3JlYXNlIGl0cyB0aW1lb3V0Lg0KPlNvIHRoYXQgcmVhZGVyIHdp bGwgd2FpdCBmb3IgcmVzcG9uc2UgZnJvbSB0YWcgZm9yIHRoZSBzdWZmaWNpZW50IHRpbWUgYmVm b3JlDQo+ZGVjbGFyaW5nIHRoZSB0aW1lb3V0IGVycm9yLg0KPg0KPg0KPj4gKyAgICAgICAgICAg IHJlc3VsdCA9IGlzbzE0NDQzX2NvbmZpZ19mZHQoc3Rjb250ZXh0LA0KPj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCooKGNiX2FyZy0+c2tiX3Jlc3AtPmRhdGEp ICsgMykNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYg MHgzZikpOw0KPj4gKyAgICAgICAgICAgIGlmIChyZXN1bHQpIHsNCj4+ICsgICAgICAgICAgICAg ICAgICAgIGRldl9lcnIoZGV2LCAiQ29uZmlnLiBzZXR0aW5nIGVycm9yIG9uIFdUWCByZXEsIGVy ciA9DQo+MHgleFxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0KTsN Cj4+ICsgICAgICAgICAgICAgICAgICAgIGdvdG8gZW5kOw0KPj4gKyAgICAgICAgICAgIH0NCj4+ ICsgICAgICAgICAgICB3dHggPSB0cnVlOw0KPj4gKw0KPj4gKyAgICAgICAgICAgIC8qIEFTWU5D IHJlcSBhcyBubyByZXNwb25zZSBleHBlY3RlZCAqLw0KPj4gKyAgICAgICAgICAgIG5ld19wYXJh bXNbMF0ucGFyYW1fb2Zmc2V0ID0gMTsNCj4+ICsgICAgICAgICAgICBuZXdfcGFyYW1zWzBdLm5l d19wYXJhbV92YWwgPQ0KPj4gKyAgICAgICAgICAgICAgICAgICAgKigoY2JfYXJnLT5za2JfcmVz cC0+ZGF0YSkgKyAzKTsNCj4+ICsNCj4+ICsgICAgICAgICAgICByZXN1bHQgPSBzdDk1aGZfc2Vu ZF9jbWQoc3Rjb250ZXh0LA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBXVFhfUkVTUE9OU0UsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IDEsDQo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld19wYXJhbXMp Ow0KPj4gKyAgICAgICAgICAgIGlmIChyZXN1bHQpIHsNCj4+ICsgICAgICAgICAgICAgICAgICAg IGRldl9lcnIoZGV2LCAiV1RYIHJlc3BvbnNlIHNlbmQsIGVyciA9IDB4JXhcbiIsDQo+cmVzdWx0 KTsNCj4+ICsgICAgICAgICAgICAgICAgICAgIGdvdG8gZW5kOw0KPj4gKyAgICAgICAgICAgIH0N Cj4+ICsgICAgICAgICAgICByZXR1cm4gSVJRX0hBTkRMRUQ7DQo+PiArICAgIH0NCj5BIGZldyBj b21tZW50czoNCj4NCj4tIFlvdSBwcm9iYWJseSB3YW50IHRvIGRlZmluZSBhIHN0cnVjdCBza19i dWZmICpza2JfcmVzcCA9DQo+ICBjYl9hcmctPnNrYl9yZXNwDQo+DQo+T2suIEkgd2lsbCBzaW1w bGlmeSB0aGUgY29kZSBieSBkZWZpbmluZyBhIGxvY2FsIHN0cnVjdHVyZSBhcyBzdHJ1Y3Qgc2tf YnVmZg0KPipza2JfcmVzcCA9DQo+ICBjYl9hcmctPnNrYl9yZXNwLg0KPg0KPi0gKigoY2JfYXJn LT5za2JfcmVzcC0+ZGF0YSkgKyAyKSBiZWNvbWVzIHNrYl9yZXNwLT5kYXRhWzJdDQo+DQo+T2su IFdpbGwgbW9kaWZ5IHRoZSB3aG9sZSBjb2RlIGFjY29yZGluZ2x5Lg0KPg0KPi0gVGhpcyBoYW5k bGVyIGlzIGFsbW9zdCAyMDAgbGluZXMgb2YgY29kZSBsb25nLCBpdCBjb3VsZCBiZSBzcGxpdHRl ZCBpbg0KPiAgc21hbGxlciByb3V0aW5lczoNCj4gICAgICAgKiBPbmUgZm9yIGhhbmRsaW5nIEZX VCBmcm9tIHRhZw0KPiAgICAgICAqIE9uZSBmb3IgaGFuZGxpbmcgSS9PIGVycm9ycw0KPiAgICAg ICAqIE9uZSBmb3IgYWN0dWFsbHkgcHJvY2Vzc2luZyB0aGUgcmVzcG9uc2UgT2suDQo+SSB3aWxs IHNwbGl0IHRoZSBoYW5kbGVyIHRvIG1ha2UgaXQgbW9yZSBtb2R1bGFyLg0KPg0KPj4gK3N0YXRp YyBzdHJ1Y3QgbmZjX2RpZ2l0YWxfb3BzIHN0OTVoZl9uZmNfZGlnaXRhbF9vcHMgPSB7DQo+PiAr ICAgIC5pbl9jb25maWd1cmVfaHcgPSBzdDk1aGZfaW5fY29uZmlndXJlX2h3LA0KPj4gKyAgICAu aW5fc2VuZF9jbWQgPSBzdDk1aGZfaW5fc2VuZF9jbWQsDQo+PiArDQo+PiArICAgIC50Z19saXN0 ZW4gPSBzdDk1aGZfdGdfbGlzdGVuLA0KPj4gKyAgICAudGdfY29uZmlndXJlX2h3ID0gc3Q5NWhm X3RnX2NvbmZpZ3VyZV9odywNCj4+ICsgICAgLnRnX3NlbmRfY21kID0gc3Q5NWhmX3RnX3NlbmRf Y21kLA0KPj4gKyAgICAudGdfZ2V0X3JmX3RlY2ggPSBzdDk1aGZfdGdfZ2V0X3JmX3RlY2gsDQo+ PiArDQo+PiArICAgIC5zd2l0Y2hfcmYgPSBzdDk1aGZfc3dpdGNoX3JmLA0KPj4gKyAgICAuYWJv cnRfY21kID0gc3Q5NWhmX2Fib3J0X2NtZCwNCj5BbGwgdGhlIGFib3ZlIG9wcyBjYW4gYmUgc3Rh dGljLg0KPg0KPk9rLg0KPg0KPj4gK3N0YXRpYyBpbnQgc3Q5NWhmX3Byb2JlKHN0cnVjdCBzcGlf ZGV2aWNlICpuZmNfc3BpX2Rldikgew0KPj4gKyAgICBpbnQgcmV0Ow0KPj4gKw0KPj4gKyAgICBz dHJ1Y3Qgc3Q5NWhmX2NvbnRleHQgKnN0OTVjb250ZXh0Ow0KPj4gKyAgICBzdHJ1Y3Qgc3BpX2Nv bnRleHQgKnNwaWNvbnRleHQ7DQo+PiArICAgIHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBuZmNf c3BpX2Rldi0+ZGV2Lm9mX25vZGU7DQo+PiArDQo+PiArICAgIHByX2luZm8oIlNUIFNQSSBTTEFW RSBEUklWRVIgKFNUOTVIRiBSL1cgMTQ0NDNBL0IpIFBST0JFDQo+Q0FMTEVEXG4iKTsNCj4+ICsN Cj4+ICsgICAgc3Q5NWNvbnRleHQgPSBkZXZtX2t6YWxsb2MoJm5mY19zcGlfZGV2LT5kZXYsDQo+ PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgc3Q5NWhmX2Nv bnRleHQpLA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRlBfS0VSTkVMKTsN Cj4+ICsgICAgaWYgKCFzdDk1Y29udGV4dCkNCj4+ICsgICAgICAgICAgICByZXR1cm4gLUVOT01F TTsNCj4+ICsNCj4+ICsgICAgc3BpY29udGV4dCA9ICZzdDk1Y29udGV4dC0+c3BpY29udGV4dDsN Cj4+ICsNCj4+ICsgICAgc3BpY29udGV4dC0+c3BpZGV2ID0gbmZjX3NwaV9kZXY7DQo+PiArDQo+ PiArICAgIHN0OTVjb250ZXh0LT5md2kgPQ0KPj4gK2NtZF9hcnJheVtJU08xNDQ0M0FfUFJPVE9D T0xfU0VMRUNUXS5jbWRfcGFyYW1zWzJdOw0KPj4gKw0KPj4gKyAgICBpZiAob2ZfZ2V0X3Byb3Bl cnR5KG5wLCAic3Q5NWhmdmluLXN1cHBseSIsIE5VTEwpKSB7DQo+UGxlYXNlIHVzZSBkZXZpY2Vf cHJvcGVydHlfcHJlc2VudCB0byBiZSBmaXJtd2FyZSBBUEkgYWdub3N0aWMuDQo+DQo+T2suDQo+ DQo+VGhhbmtzISENCj5CZXN0IFJlZ2FyZHMsDQo+U2hpa2hhDQo= ^ permalink raw reply [flat|nested] 7+ messages in thread
* [[linux-nfc] PATCH v1.0 3/3] DT: bindings: net: nfc: ST95HF binding doc 2015-09-12 7:21 [[linux-nfc] PATCH v1.0 0/3] Add support for ST95HF Shikha Singh 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 1/3] NFC: digital: Type4A tags support Shikha Singh 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support Shikha Singh @ 2015-09-12 7:21 ` Shikha Singh 2 siblings, 0 replies; 7+ messages in thread From: Shikha Singh @ 2015-09-12 7:21 UTC (permalink / raw) To: sameo, aloisio.almeida, lauro.venancio, linux-wireless, linux-nfc Cc: raunaque.quaiser, manoj.kumar, sylvain.fidelis, patrick.sohn, shikha.singh This patch includes ST95HF binding doc that guides how to make node entry of ST95HF in DT file of any platform. Signed-off-by: Shikha Singh <shikha.singh@st.com> --- .../devicetree/bindings/net/nfc/st95hf.txt | 55 ++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/nfc/st95hf.txt diff --git a/Documentation/devicetree/bindings/net/nfc/st95hf.txt b/Documentation/devicetree/bindings/net/nfc/st95hf.txt new file mode 100644 index 0000000..baa4819 --- /dev/null +++ b/Documentation/devicetree/bindings/net/nfc/st95hf.txt @@ -0,0 +1,55 @@ +STMicroelectronics NFC Transceiver ST95HF +----------------------------------------- + +ST NFC Transceiver is required to attach with SPI bus. +ST95HF should be defined in DT as SPI slave device of SPI master +with which transceiver is physically connected. +The properties defined below are required to be the part of DT +to include transceiver into the platform. + +Required properties: + +- reg: Address of SPI slave "transceiver" on SPI master bus. + +- compatible: should be "st,st95hf" for ST NFC transceiver + +- spi-max-frequency: Max. operating SPI frequency for transceiver. + +- st,st95hf-enable-gpio: GPIO line used to enable transceiver. + +- interrupt-parent : Standard way to specify the controller to which + transceiver interrupt is routed. + +- interrupts : Standard way to define device (transceiver's out) interrupt. + +Optional property: + +- st95hfvin-supply : This is an optional property.It contains a phandle to + transceiver regulator supply node in DT. + +Example: + spi@9840000 { + compatible = "st,comms-ssc4-spi"; + reg = <0x9840000 0x110>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>; + clock-names = "ssc"; + pinctrl-0 = <&pinctrl_spi0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + cs-gpios = <&pio0 4>; + status = "okay"; + + st95hf@0{ + reg = <0>; + compatible = "st,st95hf"; + status = "okay"; + spi-max-frequency = <1000000>; + st,st95hf-enable-gpio = <&pio4 0>; + interrupt-parent = <&pio0>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + }; + + }; + -- 1.8.2.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-11-06 9:14 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-09-12 7:21 [[linux-nfc] PATCH v1.0 0/3] Add support for ST95HF Shikha Singh 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 1/3] NFC: digital: Type4A tags support Shikha Singh 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 2/3] driver: nfc: st95hf: ST NFC Transceiver support Shikha Singh 2015-10-22 6:24 ` Samuel Ortiz 2015-10-26 5:57 ` Shikha SINGH 2015-11-06 9:13 ` Shikha SINGH 2015-09-12 7:21 ` [[linux-nfc] PATCH v1.0 3/3] DT: bindings: net: nfc: ST95HF binding doc Shikha Singh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox