/*
* --------------------------------------------------------------------
* Driver for ST NFC Transceiver ST95HF
* --------------------------------------------------------------------
* Copyright (C) 2015 STMicroelectronics Pvt. Ltd. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/nfc.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/wait.h>
#include <net/nfc/digital.h>
#include <net/nfc/nfc.h>
#include "spi.h"
/* supported protocols */
#define ST95HF_SUPPORTED_PROT (NFC_PROTO_ISO14443_MASK | \
NFC_PROTO_ISO14443_B_MASK | \
NFC_PROTO_ISO15693_MASK)
/* driver capabilities */
#define ST95HF_CAPABILITIES NFC_DIGITAL_DRV_CAPS_IN_CRC
/* Command Send Interface */
/* ST95HF_COMMAND_SEND CMD Ids */
#define ECHO_CMD 0x55
#define WRITE_REGISTER_CMD 0x9
#define PROTOCOL_SELECT_CMD 0x2
#define SEND_RECEIVE_CMD 0x4
/* Select protocol codes */
#define ISO15693_PROTOCOL_CODE 0x1
#define ISO14443A_PROTOCOL_CODE 0x2
#define ISO14443B_PROTOCOL_CODE 0x3
/*
* 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/ISO15693,
* hence the max value 1 should be
* taken.
*/
#define ST95HF_TAILROOM_LEN 1
/* Command Response interface */
#define MAX_RESPONSE_BUFFER_SIZE 280
#define ECHORESPONSE 0x55
#define ST95HF_ERR_MASK 0xF
#define ST95HF_TIMEOUT_ERROR 0x87
#define ST95HF_NFCA_CRC_ERR_MASK 0x20
#define ST95HF_NFCB_CRC_ERR_MASK 0x01
/* ST95HF transmission flag values */
#define TRFLAG_NFCA_SHORT_FRAME 0x07
#define TRFLAG_NFCA_STD_FRAME 0x08
#define TRFLAG_NFCA_STD_FRAME_CRC 0x28
/* Misc defs */
#define HIGH 1
#define LOW 0
#define ISO14443A_RATS_REQ 0xE0
#define RATS_TB1_PRESENT_MASK 0x20
#define RATS_TA1_PRESENT_MASK 0x10
#define TB1_FWI_MASK 0xF0
#define WTX_REQ_FROM_TAG 0xF2
#define MAX_CMD_LEN 0x7
#define MAX_CMD_PARAMS 4
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;
};
/*
* List of top-level cmds to be used internally by the driver.
* All these commands are build on top of ST95HF basic commands
* such as SEND_RECEIVE_CMD, PROTOCOL_SELECT_CMD, etc.
* These top level cmds are used internally while implementing various ops of
* digital layer/driver probe or extending the digital framework layer for
* features that are not yet implemented there, for example, WTX cmd handling.
*/
enum st95hf_cmd_list {
CMD_ECHO,
CMD_ISO14443A_CONFIG,
CMD_ISO14443A_DEMOGAIN,
CMD_ISO14443B_DEMOGAIN,
CMD_ISO14443A_PROTOCOL_SELECT,
CMD_ISO14443B_PROTOCOL_SELECT,
CMD_WTX_RESPONSE,
CMD_FIELD_OFF,
CMD_ISO15693_PROTOCOL_SELECT,
};
static const struct cmd cmd_array[] = {
[CMD_ECHO] = {
.cmd_len = 0x2,
.cmd_id = ECHO_CMD,
.no_cmd_params = 0,
.req = SYNC,
},
[CMD_ISO14443A_CONFIG] = {
.cmd_len = 0x7,
.cmd_id = WRITE_REGISTER_CMD,
.no_cmd_params = 0x4,
.cmd_params = {0x3A, 0x00, 0x5A, 0x04},
.req = SYNC,
},
[CMD_ISO14443A_DEMOGAIN] = {
.cmd_len = 0x7,
.cmd_id = WRITE_REGISTER_CMD,
.no_cmd_params = 0x4,
.cmd_params = {0x68, 0x01, 0x01, 0xDF},
.req = SYNC,
},
[CMD_ISO14443B_DEMOGAIN] = {
.cmd_len = 0x7,
.cmd_id = WRITE_REGISTER_CMD,
.no_cmd_params = 0x4,
.cmd_params = {0x68, 0x01, 0x01, 0x51},
.req = SYNC,
},
[CMD_ISO14443A_PROTOCOL_SELECT] = {
.cmd_len = 0x7,
.<