/*
* NFC Digital Protocol stack
* Copyright (c) 2013, Intel Corporation.
*
* 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 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.
*
*/
#define pr_fmt(fmt) "digital: %s: " fmt, __func__
#include "digital.h"
#define DIGITAL_CMD_SENS_REQ 0x26
#define DIGITAL_CMD_ALL_REQ 0x52
#define DIGITAL_CMD_SEL_REQ_CL1 0x93
#define DIGITAL_CMD_SEL_REQ_CL2 0x95
#define DIGITAL_CMD_SEL_REQ_CL3 0x97
#define DIGITAL_SDD_REQ_SEL_PAR 0x20
#define DIGITAL_SDD_RES_CT 0x88
#define DIGITAL_SDD_RES_LEN 5
#define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04))
#define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60))
#define DIGITAL_SEL_RES_IS_T4T(sel_res) ((sel_res) & 0x20)
#define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40)
#define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x0C00) == 0x0C00)
#define DIGITAL_SENS_RES_IS_VALID(sens_res) \
((!((sens_res) & 0x001F) && (((sens_res) & 0x0C00) == 0x0C00)) || \
(((sens_res) & 0x001F) && ((sens_res) & 0x0C00) != 0x0C00))
#define DIGITAL_MIFARE_READ_RES_LEN 16
#define DIGITAL_MIFARE_ACK_RES 0x0A
#define DIGITAL_CMD_SENSB_REQ 0x05
#define DIGITAL_SENSB_ADVANCED BIT(5)
#define DIGITAL_SENSB_EXTENDED BIT(4)
#define DIGITAL_SENSB_ALLB_REQ BIT(3)
#define DIGITAL_SENSB_N(n) ((n) & 0x7)
#define DIGITAL_CMD_SENSB_RES 0x50
#define DIGITAL_CMD_ATTRIB_REQ 0x1D
#define DIGITAL_ATTRIB_P1_TR0_DEFAULT (0x0 << 6)
#define DIGITAL_ATTRIB_P1_TR1_DEFAULT (0x0 << 4)
#define DIGITAL_ATTRIB_P1_SUPRESS_EOS BIT(3)
#define DIGITAL_ATTRIB_P1_SUPRESS_SOS BIT(2)
#define DIGITAL_ATTRIB_P2_LISTEN_POLL_1 (0x0 << 6)
#define DIGITAL_ATTRIB_P2_POLL_LISTEN_1 (0x0 << 4)
#define DIGITAL_ATTRIB_P2_MAX_FRAME_256 0x8
#define DIGITAL_ATTRIB_P4_DID(n) ((n) & 0xf)
#define DIGITAL_CMD_SENSF_REQ 0x00
#define DIGITAL_CMD_SENSF_RES 0x01
#define DIGITAL_SENSF_RES_MIN_LENGTH 17
#define DIGITAL_SENSF_RES_RD_AP_B1 0x00
#define DIGITAL_SENSF_RES_RD_AP_B2 0x8F
#define DIGITAL_SENSF_REQ_RC_NONE 0
#define DIGITAL_SENSF_REQ_RC_SC 1
#define DIGITAL_SENSF_REQ_RC_AP 2
#define DIGITAL_CMD_ISO15693_INVENTORY_REQ 0x01
#define DIGITAL_ISO15693_REQ_FLAG_DATA_RATE BIT(1)
#define DIGITAL_ISO15693_REQ_FLAG_INVENTORY BIT(2)
#define DIGITAL_ISO15693_REQ_FLAG_NB_SLOTS BIT(5)
#define DIGITAL_ISO15693_RES_FLAG_ERROR BIT(0)
#define DIGITAL_ISO15693_RES_IS_VALID(flags) \
(!((flags) & DIGITAL_ISO15693_RES_FLAG_ERROR))
#define DIGITAL_ISO_DEP_I_PCB 0x02
#define DIGITAL_ISO_DEP_PNI(pni) ((pni) & 0x01)
#define DIGITAL_ISO_DEP_PCB_TYPE(pcb) ((pcb) & 0xC0)
#define DIGITAL_ISO_DEP_I_BLOCK 0x00
#define DIGITAL_ISO_DEP_BLOCK_HAS_DID(pcb) ((pcb) & 0x08)
static const u8 digital_ats_fsc[] = {
16, 24, 32, 40, 48, 64, 96, 128,
};
#define DIGITAL_ATS_FSCI(t0) ((t0) & 0x0F)
#define DIGITAL_SENSB_FSCI(pi2) (((pi2) & 0xF0) >> 4)
#define DIGITAL_ATS_MAX_FSC 256
#define DIGITAL_RATS_BYTE1 0xE0
#define DIGITAL_RATS_PARAM 0x80
struct digital_sdd_res {
u8 nfcid1[4];
u8 bcc;
} __packed;
struct digital_sel_req {
u8 sel_cmd;
u8 b2;
u8 nfcid1[4];
u8 bcc;
} __packed;
struct digital_sensb_req {
u8 cmd;
u8 afi;
u8 param;
} __packed;
struct digital_sensb_res {
u8 cmd;
u8 nfcid0[4];
u8 app_data[4];
u8 proto_info[3];
} __packed;
struct digital_attrib_req {
u8 cmd;
u8 nfcid0[4];
u8 param1;
u8 param2;
u8 param3;
u8 param4;
} __packed;
struct digital_attrib_res {
u8 mbli_did;
} __packed;
struct digital_sensf_req {
u8 cmd;
u8 sc1;
u8 sc2;
u8 rc;
u8 tsn;
} __packed;
struct digital_sensf_res {
u8 cmd;
u8 nfcid2[8];
u8 pad0[2];
u8 pad1[3];
u8 mrti_check;
u8 mrti_update;
u8 pad2;
u8 rd[2];
} __packed;
struct digital_iso15693_inv_req {
u8 flags;
u8 cmd;
u8 mask_len;
u64 mask;
} __packed;
struct digital_iso15693_inv_res {
u8 flags;
u8 dsfid;
u64 uid;
} __packed;
static int digital_in_send_sdd_req