NFC: 3.18 pull request

This is the NFC pull request for 3.18.
 
 We've had major updates for TI and ST Microelectronics drivers:
 
 For TI's trf7970a driver:
 
 - Target mode support for trf7970a
 - Suspend/resume support for trf7970a
 - DT properties additions to handle different quirks
 - A bunch of fixes for smartphone IOP related issues
 
 For ST Microelectronics' ST21NFCA and ST21NFCB drivers:
 
 - ISO15693 support for st21nfcb
 - checkpatch and sparse related warning fixes
 - Code cleanups and a few minor fixes
 
 Finally, Marvell add ISO15693 support to the NCI stack, together with a
 couple of NCI fixes.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJUIg4oAAoJEIqAPN1PVmxKg+kP/RPrgH6LA1tFubIwKR2+sGQ7
 g/W2J3AE8QASZkErkpXRNCt2D/SPWEKBY/qscwz+BtcWg76taIIaGTvVUNtxSaW3
 gS4hG6V1UlANWv3KFfaOKmzjEOO/SPNtkFAyI0cTOaGyUqG4o9BgBZpn1rYO16MD
 ZkSC39MpjMoXB9BbsfQngoUEoWc3tZNMmRzk4IVTwE/wXuQvZxmFQXEAiZ+pnYle
 NQfugaGMz0526rLG3QnrpkUakFb81iQwtONpbx6i8KW/Klkc6TN/ek6J9ecU8t5z
 tdHOViZWRmA1VwMGBHwpq8F2o/ATH6GeivTgqrQjcjGNhCUUT1Ulzve2UxGEMWi6
 ncjKY/GxUrYaMMtRvLv+/knrfbWtd+EnWOav07jgNrrA0tvgBNQvEKKHPoWykDVN
 QKpxu3YoNxrsR/LJMS+Zjj0IIM1Y+9DTOkLXzxJ5Hvht8rOl5heYGh2DICOpWsbQ
 ejrQicJOJvN5vqu+Sgcqq4msyTEdbs2LfRDrW1VC9A6ILI+KzYg2laTFGMnhZ5qn
 TgsYIDdONS2iGUulFHylGHI7ANtUg/mhklLUccY1HQYyiAM1NQUtzq1tAz6yLoIH
 l8iIiyzJSBWW57nWhyrULEbzHgPE+bHIjO4T+UUOxMgquYa4V11S1uP0OfWfZogR
 xS24GlobS2oXHMQqh0fA
 =d/C+
 -----END PGP SIGNATURE-----

Merge tag 'nfc-next-3.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-next

Samuel Ortiz <sameo@linux.intel.com> says:

"NFC: 3.18 pull request

This is the NFC pull request for 3.18.

We've had major updates for TI and ST Microelectronics drivers:

For TI's trf7970a driver:

- Target mode support for trf7970a
- Suspend/resume support for trf7970a
- DT properties additions to handle different quirks
- A bunch of fixes for smartphone IOP related issues

For ST Microelectronics' ST21NFCA and ST21NFCB drivers:

- ISO15693 support for st21nfcb
- checkpatch and sparse related warning fixes
- Code cleanups and a few minor fixes

Finally, Marvell add ISO15693 support to the NCI stack, together with a
couple of NCI fixes."

Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
John W. Linville 2014-09-26 13:37:02 -04:00
commit 330bd4ec9d
18 changed files with 1219 additions and 385 deletions

View File

@ -26,7 +26,7 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on I2C2):
clock-frequency = <400000>;
interrupt-parent = <&gpio5>;
interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
reset-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
};

View File

@ -13,6 +13,11 @@ Optional SoC Specific Properties:
- pinctrl-names: Contains only one value - "default".
- pintctrl-0: Specifies the pin control groups used for this controller.
- autosuspend-delay: Specify autosuspend delay in milliseconds.
- vin-voltage-override: Specify voltage of VIN pin in microvolts.
- irq-status-read-quirk: Specify that the trf7970a being used has the
"IRQ Status Read" erratum.
- en2-rf-quirk: Specify that the trf7970a being used has the "EN2 RF"
erratum.
Example (for ARM-based BeagleBone with TRF7970A on SPI1):
@ -30,7 +35,10 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
ti,enable-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>,
<&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
autosuspend-delay = <30000>;
irq-status-read-quirk;
en2-rf-quirk;
status = "okay";
};
};

View File

@ -271,6 +271,7 @@ static int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb)
static int get_frame_size(u8 *buf, int buflen)
{
int len = 0;
if (buf[len + 1] == ST21NFCA_SOF_EOF)
return 0;
@ -311,6 +312,7 @@ static int check_crc(u8 *buf, int buflen)
static int st21nfca_hci_i2c_repack(struct sk_buff *skb)
{
int i, j, r, size;
if (skb->len < 1 || (skb->len > 1 && skb->data[1] != 0))
return -EBADMSG;
@ -525,24 +527,19 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client)
}
/* GPIO request and configuration */
r = devm_gpio_request(&client->dev, gpio, "clf_enable");
r = devm_gpio_request_one(&client->dev, gpio, GPIOF_OUT_INIT_HIGH,
"clf_enable");
if (r) {
nfc_err(&client->dev, "Failed to request enable pin\n");
return -ENODEV;
}
r = gpio_direction_output(gpio, 1);
if (r) {
nfc_err(&client->dev, "Failed to set enable pin direction as output\n");
return -ENODEV;
}
phy->gpio_ena = gpio;
/* IRQ */
r = irq_of_parse_and_map(pp, 0);
if (r < 0) {
nfc_err(&client->dev,
"Unable to get irq, error: %d\n", r);
nfc_err(&client->dev, "Unable to get irq, error: %d\n", r);
return r;
}
@ -576,32 +573,20 @@ static int st21nfca_hci_i2c_request_resources(struct i2c_client *client)
phy->gpio_ena = pdata->gpio_ena;
phy->irq_polarity = pdata->irq_polarity;
r = devm_gpio_request(&client->dev, phy->gpio_irq, "wake_up");
r = devm_gpio_request_one(&client->dev, phy->gpio_irq, GPIOF_IN,
"wake_up");
if (r) {
pr_err("%s : gpio_request failed\n", __FILE__);
return -ENODEV;
}
r = gpio_direction_input(phy->gpio_irq);
if (r) {
pr_err("%s : gpio_direction_input failed\n", __FILE__);
return -ENODEV;
}
if (phy->gpio_ena > 0) {
r = devm_gpio_request(&client->dev,
phy->gpio_ena, "clf_enable");
r = devm_gpio_request_one(&client->dev, phy->gpio_ena,
GPIOF_OUT_INIT_HIGH, "clf_enable");
if (r) {
pr_err("%s : ena gpio_request failed\n", __FILE__);
return -ENODEV;
}
r = gpio_direction_output(phy->gpio_ena, 1);
if (r) {
pr_err("%s : ena gpio_direction_output failed\n",
__FILE__);
return -ENODEV;
}
}
/* IRQ */
@ -711,7 +696,6 @@ static struct i2c_driver st21nfca_hci_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = ST21NFCA_HCI_I2C_DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_st21nfca_i2c_match),
},
.probe = st21nfca_hci_i2c_probe,

View File

@ -34,7 +34,7 @@
#define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30
#define ST21NFCA_RF_READER_ISO15693_GATE 0x12
#define ST21NFCA_RF_READER_ISO15693_INVENTORY 0x01
#define ST21NFCA_RF_READER_ISO15693_INVENTORY 0x01
/*
* Reader gate for communication with contact-less cards using Type A
@ -45,21 +45,42 @@
#define ST21NFCA_RF_READER_14443_3_A_ATQA 0x03
#define ST21NFCA_RF_READER_14443_3_A_SAK 0x04
#define ST21NFCA_RF_READER_F_DATARATE 0x01
#define ST21NFCA_RF_READER_F_DATARATE_106 0x01
#define ST21NFCA_RF_READER_F_DATARATE_212 0x02
#define ST21NFCA_RF_READER_F_DATARATE_424 0x04
#define ST21NFCA_RF_READER_F_POL_REQ 0x02
#define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT 0xffff0000
#define ST21NFCA_RF_READER_F_NFCID2 0x03
#define ST21NFCA_RF_READER_F_NFCID1 0x04
#define ST21NFCA_RF_CARD_F_MODE 0x01
#define ST21NFCA_RF_CARD_F_NFCID2_LIST 0x04
#define ST21NFCA_RF_CARD_F_NFCID1 0x05
#define ST21NFCA_RF_CARD_F_SENS_RES 0x06
#define ST21NFCA_RF_CARD_F_SEL_RES 0x07
#define ST21NFCA_RF_CARD_F_DATARATE 0x08
#define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01
#define ST21NFCA_DEVICE_MGNT_GATE 0x01
#define ST21NFCA_DEVICE_MGNT_PIPE 0x02
#define ST21NFCA_DM_GETINFO 0x13
#define ST21NFCA_DM_GETINFO_PIPE_LIST 0x02
#define ST21NFCA_DM_GETINFO_PIPE_INFO 0x01
#define ST21NFCA_DM_PIPE_CREATED 0x02
#define ST21NFCA_DM_PIPE_OPEN 0x04
#define ST21NFCA_DM_RF_ACTIVE 0x80
#define ST21NFCA_DM_DISCONNECT 0x30
#define ST21NFCA_DM_GETINFO 0x13
#define ST21NFCA_DM_GETINFO_PIPE_LIST 0x02
#define ST21NFCA_DM_GETINFO_PIPE_INFO 0x01
#define ST21NFCA_DM_PIPE_CREATED 0x02
#define ST21NFCA_DM_PIPE_OPEN 0x04
#define ST21NFCA_DM_RF_ACTIVE 0x80
#define ST21NFCA_DM_DISCONNECT 0x30
#define ST21NFCA_DM_IS_PIPE_OPEN(p) \
((p & 0x0f) == (ST21NFCA_DM_PIPE_CREATED | ST21NFCA_DM_PIPE_OPEN))
#define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/
#define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/
#define ST21NFCA_EVT_FIELD_ON 0x11
#define ST21NFCA_EVT_CARD_DEACTIVATED 0x12
#define ST21NFCA_EVT_CARD_ACTIVATED 0x13
#define ST21NFCA_EVT_FIELD_OFF 0x14
static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES);
@ -355,8 +376,8 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
if (r < 0)
return r;
pol_req =
be32_to_cpu(ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
pol_req = be32_to_cpu((__force __be32)
ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
ST21NFCA_RF_READER_F_POL_REQ,
(u8 *) &pol_req, 4);
@ -790,6 +811,7 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
struct nfc_target *target)
{
u8 fwi = 0x11;
switch (target->hci_reader_gate) {
case NFC_HCI_RF_READER_A_GATE:
case NFC_HCI_RF_READER_B_GATE:
@ -839,20 +861,16 @@ static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate,
if (gate == ST21NFCA_RF_CARD_F_GATE) {
r = st21nfca_tm_event_send_data(hdev, skb, gate);
if (r < 0)
goto exit;
return r;
return 0;
} else {
info->dep_info.curr_nfc_dep_pni = 0;
return 1;
}
break;
info->dep_info.curr_nfc_dep_pni = 0;
return 1;
default:
return 1;
}
kfree_skb(skb);
return 0;
exit:
return r;
}
static struct nfc_hci_ops st21nfca_hci_ops = {
@ -904,8 +922,11 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
* persistent info to discriminate 2 identical chips
*/
dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES);
if (dev_num >= ST21NFCA_NUM_DEVICES)
goto err_alloc_hdev;
return -ENODEV;
set_bit(dev_num, dev_mask);
scnprintf(init_data.session_id, sizeof(init_data.session_id), "%s%2x",
"ST21AH", dev_num);

View File

@ -82,30 +82,9 @@ struct st21nfca_hci_info {
#define ST21NFCA_WR_XCHG_DATA 0x10
#define ST21NFCA_RF_READER_F_GATE 0x14
#define ST21NFCA_RF_READER_F_DATARATE 0x01
#define ST21NFCA_RF_READER_F_DATARATE_106 0x01
#define ST21NFCA_RF_READER_F_DATARATE_212 0x02
#define ST21NFCA_RF_READER_F_DATARATE_424 0x04
#define ST21NFCA_RF_READER_F_POL_REQ 0x02
#define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT 0xffff0000
#define ST21NFCA_RF_READER_F_NFCID2 0x03
#define ST21NFCA_RF_READER_F_NFCID1 0x04
#define ST21NFCA_RF_READER_F_SENS_RES 0x05
#define ST21NFCA_RF_CARD_F_GATE 0x24
#define ST21NFCA_RF_CARD_F_MODE 0x01
#define ST21NFCA_RF_CARD_F_NFCID2_LIST 0x04
#define ST21NFCA_RF_CARD_F_NFCID1 0x05
#define ST21NFCA_RF_CARD_F_SENS_RES 0x06
#define ST21NFCA_RF_CARD_F_SEL_RES 0x07
#define ST21NFCA_RF_CARD_F_DATARATE 0x08
#define ST21NFCA_RF_CARD_F_DATARATE_106 0x00
#define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01
#define ST21NFCA_EVT_SEND_DATA 0x10
#define ST21NFCA_EVT_FIELD_ON 0x11
#define ST21NFCA_EVT_CARD_DEACTIVATED 0x12
#define ST21NFCA_EVT_CARD_ACTIVATED 0x13
#define ST21NFCA_EVT_FIELD_OFF 0x14
#endif /* __LOCAL_ST21NFCA_H_ */

View File

@ -121,6 +121,7 @@ static void st21nfca_tx_work(struct work_struct *work)
struct nfc_dev *dev;
struct sk_buff *skb;
if (info) {
dev = info->hdev->ndev;
skb = info->dep_info.tx_pending;
@ -128,9 +129,8 @@ static void st21nfca_tx_work(struct work_struct *work)
device_lock(&dev->dev);
nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
ST21NFCA_WR_XCHG_DATA,
skb->data, skb->len,
info->async_cb, info);
ST21NFCA_WR_XCHG_DATA, skb->data, skb->len,
info->async_cb, info);
device_unlock(&dev->dev);
kfree_skb(skb);
}
@ -185,8 +185,10 @@ static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
info->dep_info.curr_nfc_dep_pni = 0;
return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
kfree_skb(skb);
return r;
}
static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
@ -197,10 +199,6 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
int r;
skb_trim(skb, skb->len - 1);
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
goto exit;
}
if (!skb->len) {
r = -EIO;
@ -214,6 +212,11 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
atr_req = (struct st21nfca_atr_req *)skb->data;
if (atr_req->length < sizeof(struct st21nfca_atr_req)) {
r = -EPROTO;
goto exit;
}
r = st21nfca_tm_send_atr_res(hdev, atr_req);
if (r)
goto exit;
@ -237,7 +240,6 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
struct st21nfca_psl_res *psl_res;
struct sk_buff *skb;
u8 bitrate[2] = {0, 0};
int r;
skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL);
@ -254,6 +256,8 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
if (r < 0)
goto error;
/*
* ST21NFCA only support P2P passive.
@ -269,8 +273,11 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
}
/* Send an event to change bitrate change event to card f */
return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
ST21NFCA_EVT_CARD_F_BITRATE, bitrate, 2);
error:
kfree_skb(skb);
return r;
}
static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
@ -280,11 +287,6 @@ static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
int r;
skb_trim(skb, skb->len - 1);
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
skb = NULL;
goto exit;
}
if (!skb->len) {
r = -EIO;
@ -314,7 +316,7 @@ int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb)
*skb_push(skb, 1) = skb->len;
r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
kfree_skb(skb);
return r;
@ -330,11 +332,6 @@ static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
skb_trim(skb, skb->len - 1);
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
skb = NULL;
goto exit;
}
size = 4;
@ -368,12 +365,6 @@ static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
break;
}
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
skb = NULL;
goto exit;
}
skb_pull(skb, size);
return nfc_tm_data_received(hdev->ndev, skb);
@ -437,8 +428,6 @@ static void st21nfca_im_send_psl_req(struct nfc_hci_dev *hdev, u8 did, u8 bsi,
*skb_push(skb, 1) = info->dep_info.to | 0x10;
st21nfca_im_send_pdu(info, skb);
kfree_skb(skb);
}
#define ST21NFCA_CB_TYPE_READER_F 1
@ -452,7 +441,7 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
if (err != 0)
return;
if (IS_ERR(skb))
if (!skb)
return;
switch (info->async_cb_type) {
@ -484,8 +473,7 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
ST21NFCA_PP2LRI(atr_res->ppi));
break;
default:
if (err == 0)
kfree_skb(skb);
kfree_skb(skb);
break;
}
}
@ -522,7 +510,7 @@ int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len)
memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
target = hdev->ndev->targets;
if (target->sensf_res)
if (target->sensf_res_len > 0)
memcpy(atr_req->nfcid3, target->sensf_res,
target->sensf_res_len);
else
@ -565,7 +553,7 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
if (err != 0)
return;
if (IS_ERR(skb))
if (!skb)
return;
switch (info->async_cb_type) {
@ -615,8 +603,7 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
}
exit:
if (err == 0)
kfree_skb(skb);
kfree_skb(skb);
}
int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb)

View File

@ -17,24 +17,16 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/crc-ccitt.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/nfc.h>
#include <linux/firmware.h>
#include <linux/unaligned/access_ok.h>
#include <linux/platform_data/st21nfcb.h>
#include <net/nfc/nci.h>
#include <net/nfc/llc.h>
#include <net/nfc/nfc.h>
#include "ndlc.h"
#define DRIVER_DESC "NCI NFC driver for ST21NFCB"
@ -63,12 +55,6 @@ struct st21nfcb_i2c_phy {
unsigned int irq_polarity;
int powered;
/*
* < 0 if hardware error occured (e.g. i2c err)
* and prevents normal operation.
*/
int hard_fault;
};
#define I2C_DUMP_SKB(info, skb) \
@ -122,8 +108,8 @@ static int st21nfcb_nci_i2c_write(void *phy_id, struct sk_buff *skb)
I2C_DUMP_SKB("st21nfcb_nci_i2c_write", skb);
if (phy->hard_fault != 0)
return phy->hard_fault;
if (phy->ndlc->hard_fault != 0)
return phy->ndlc->hard_fault;
r = i2c_master_send(client, skb->data, skb->len);
if (r == -EREMOTEIO) { /* Retry, chip was in standby */
@ -168,11 +154,11 @@ static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy,
if (r == -EREMOTEIO) { /* Retry, chip was in standby */
usleep_range(1000, 4000);
r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE);
} else if (r != ST21NFCB_NCI_I2C_MIN_SIZE) {
nfc_err(&client->dev, "cannot read ndlc & nci header\n");
return -EREMOTEIO;
}
if (r != ST21NFCB_NCI_I2C_MIN_SIZE)
return -EREMOTEIO;
len = be16_to_cpu(*(__be16 *) (buf + 2));
if (len > ST21NFCB_NCI_I2C_MAX_SIZE) {
nfc_err(&client->dev, "invalid frame len\n");
@ -224,7 +210,7 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id)
client = phy->i2c_dev;
dev_dbg(&client->dev, "IRQ\n");
if (phy->hard_fault)
if (phy->ndlc->hard_fault)
return IRQ_HANDLED;
if (!phy->powered) {
@ -233,13 +219,8 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id)
}
r = st21nfcb_nci_i2c_read(phy, &skb);
if (r == -EREMOTEIO) {
phy->hard_fault = r;
ndlc_recv(phy->ndlc, NULL);
if (r == -EREMOTEIO || r == -ENOMEM || r == -EBADMSG)
return IRQ_HANDLED;
} else if (r == -ENOMEM || r == -EBADMSG) {
return IRQ_HANDLED;
}
ndlc_recv(phy->ndlc, skb);
@ -273,25 +254,18 @@ static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client)
}
/* GPIO request and configuration */
r = devm_gpio_request(&client->dev, gpio, "clf_reset");
r = devm_gpio_request_one(&client->dev, gpio,
GPIOF_OUT_INIT_HIGH, "clf_reset");
if (r) {
nfc_err(&client->dev, "Failed to request reset pin\n");
return -ENODEV;
}
r = gpio_direction_output(gpio, 1);
if (r) {
nfc_err(&client->dev,
"Failed to set reset pin direction as output\n");
return -ENODEV;
}
phy->gpio_reset = gpio;
/* IRQ */
r = irq_of_parse_and_map(pp, 0);
if (r < 0) {
nfc_err(&client->dev,
"Unable to get irq, error: %d\n", r);
nfc_err(&client->dev, "Unable to get irq, error: %d\n", r);
return r;
}
@ -325,32 +299,20 @@ static int st21nfcb_nci_i2c_request_resources(struct i2c_client *client)
phy->gpio_reset = pdata->gpio_reset;
phy->irq_polarity = pdata->irq_polarity;
r = devm_gpio_request(&client->dev, phy->gpio_irq, "wake_up");
r = devm_gpio_request_one(&client->dev, phy->gpio_irq,
GPIOF_IN, "clf_irq");
if (r) {
pr_err("%s : gpio_request failed\n", __FILE__);
return -ENODEV;
}
r = gpio_direction_input(phy->gpio_irq);
if (r) {
pr_err("%s : gpio_direction_input failed\n", __FILE__);
return -ENODEV;
}
r = devm_gpio_request(&client->dev,
phy->gpio_reset, "clf_reset");
r = devm_gpio_request_one(&client->dev,
phy->gpio_reset, GPIOF_OUT_INIT_HIGH, "clf_reset");
if (r) {
pr_err("%s : reset gpio_request failed\n", __FILE__);
return -ENODEV;
}
r = gpio_direction_output(phy->gpio_reset, 1);
if (r) {
pr_err("%s : reset gpio_direction_output failed\n",
__FILE__);
return -ENODEV;
}
/* IRQ */
irq = gpio_to_irq(phy->gpio_irq);
if (irq < 0) {
@ -448,7 +410,6 @@ static struct i2c_driver st21nfcb_nci_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = ST21NFCB_NCI_I2C_DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_st21nfcb_i2c_match),
},
.probe = st21nfcb_nci_i2c_probe,

View File

@ -112,6 +112,10 @@ static void llt_ndlc_send_queue(struct llt_ndlc *ndlc)
ndlc->t1_active = true;
mod_timer(&ndlc->t1_timer, time_sent +
msecs_to_jiffies(NDLC_TIMER_T1));
/* start timer t2 for chip availability */
ndlc->t2_active = true;
mod_timer(&ndlc->t2_timer, time_sent +
msecs_to_jiffies(NDLC_TIMER_T2));
}
}
@ -207,7 +211,7 @@ static void llt_ndlc_sm_work(struct work_struct *work)
ndlc->t2_active = false;
ndlc->t1_active = false;
del_timer_sync(&ndlc->t1_timer);
del_timer_sync(&ndlc->t2_timer);
ndlc_close(ndlc);
ndlc->hard_fault = -EREMOTEIO;
}

View File

@ -42,6 +42,10 @@ struct llt_ndlc {
struct device *dev;
/*
* < 0 if hardware error occured
* and prevents normal operation.
*/
int hard_fault;
};

View File

@ -22,10 +22,11 @@
#include <net/nfc/nci_core.h>
#include "st21nfcb.h"
#include "ndlc.h"
#define DRIVER_DESC "NCI NFC driver for ST21NFCB"
#define ST21NFCB_NCI1_X_PROPRIETARY_ISO15693 0x83
static int st21nfcb_nci_open(struct nci_dev *ndev)
{
struct st21nfcb_nci_info *info = nci_get_drvdata(ndev);
@ -65,10 +66,18 @@ static int st21nfcb_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
return ndlc_send(info->ndlc, skb);
}
static __u32 st21nfcb_nci_get_rfprotocol(struct nci_dev *ndev,
__u8 rf_protocol)
{
return rf_protocol == ST21NFCB_NCI1_X_PROPRIETARY_ISO15693 ?
NFC_PROTO_ISO15693_MASK : 0;
}
static struct nci_ops st21nfcb_nci_ops = {
.open = st21nfcb_nci_open,
.close = st21nfcb_nci_close,
.send = st21nfcb_nci_send,
.get_rfprotocol = st21nfcb_nci_get_rfprotocol,
};
int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom,
@ -88,30 +97,26 @@ int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom,
| NFC_PROTO_FELICA_MASK
| NFC_PROTO_ISO14443_MASK
| NFC_PROTO_ISO14443_B_MASK
| NFC_PROTO_ISO15693_MASK
| NFC_PROTO_NFC_DEP_MASK;
ndlc->ndev = nci_allocate_device(&st21nfcb_nci_ops, protocols,
phy_headroom, phy_tailroom);
if (!ndlc->ndev) {
pr_err("Cannot allocate nfc ndev\n");
r = -ENOMEM;
goto err_alloc_ndev;
return -ENOMEM;
}
info->ndlc = ndlc;
nci_set_drvdata(ndlc->ndev, info);
r = nci_register_device(ndlc->ndev);
if (r)
goto err_regdev;
if (r) {
pr_err("Cannot register nfc device to nci core\n");
nci_free_device(ndlc->ndev);
}
return r;
err_regdev:
nci_free_device(ndlc->ndev);
err_alloc_ndev:
kfree(info);
return r;
}
EXPORT_SYMBOL_GPL(st21nfcb_nci_probe);

View File

@ -19,8 +19,6 @@
#ifndef __LOCAL_ST21NFCB_H_
#define __LOCAL_ST21NFCB_H_
#include <net/nfc/nci_core.h>
#include "ndlc.h"
/* Define private flags: */

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
* The NFC Controller Interface is the communication protocol between an
* NFC Controller (NFCC) and a Device Host (DH).
*
* Copyright (C) 2014 Marvell International Ltd.
* Copyright (C) 2011 Texas Instruments, Inc.
*
* Written by Ilan Elias <ilane@ti.com>
@ -65,19 +66,18 @@
#define NCI_NFC_F_PASSIVE_POLL_MODE 0x02
#define NCI_NFC_A_ACTIVE_POLL_MODE 0x03
#define NCI_NFC_F_ACTIVE_POLL_MODE 0x05
#define NCI_NFC_15693_PASSIVE_POLL_MODE 0x06
#define NCI_NFC_V_PASSIVE_POLL_MODE 0x06
#define NCI_NFC_A_PASSIVE_LISTEN_MODE 0x80
#define NCI_NFC_B_PASSIVE_LISTEN_MODE 0x81
#define NCI_NFC_F_PASSIVE_LISTEN_MODE 0x82
#define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83
#define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85
#define NCI_NFC_15693_PASSIVE_LISTEN_MODE 0x86
/* NCI RF Technologies */
#define NCI_NFC_RF_TECHNOLOGY_A 0x00
#define NCI_NFC_RF_TECHNOLOGY_B 0x01
#define NCI_NFC_RF_TECHNOLOGY_F 0x02
#define NCI_NFC_RF_TECHNOLOGY_15693 0x03
#define NCI_NFC_RF_TECHNOLOGY_V 0x03
/* NCI Bit Rates */
#define NCI_NFC_BIT_RATE_106 0x00
@ -87,6 +87,7 @@
#define NCI_NFC_BIT_RATE_1695 0x04
#define NCI_NFC_BIT_RATE_3390 0x05
#define NCI_NFC_BIT_RATE_6780 0x06
#define NCI_NFC_BIT_RATE_26 0x20
/* NCI RF Protocols */
#define NCI_RF_PROTOCOL_UNKNOWN 0x00
@ -95,6 +96,7 @@
#define NCI_RF_PROTOCOL_T3T 0x03
#define NCI_RF_PROTOCOL_ISO_DEP 0x04
#define NCI_RF_PROTOCOL_NFC_DEP 0x05
#define NCI_RF_PROTOCOL_T5T 0x06
/* NCI RF Interfaces */
#define NCI_RF_INTERFACE_NFCEE_DIRECT 0x00
@ -328,6 +330,12 @@ struct rf_tech_specific_params_nfcf_poll {
__u8 sensf_res[18]; /* 16 or 18 Bytes */
} __packed;
struct rf_tech_specific_params_nfcv_poll {
__u8 res_flags;
__u8 dsfid;
__u8 uid[8]; /* 8 Bytes */
} __packed;
struct nci_rf_discover_ntf {
__u8 rf_discovery_id;
__u8 rf_protocol;
@ -338,6 +346,7 @@ struct nci_rf_discover_ntf {
struct rf_tech_specific_params_nfca_poll nfca_poll;
struct rf_tech_specific_params_nfcb_poll nfcb_poll;
struct rf_tech_specific_params_nfcf_poll nfcf_poll;
struct rf_tech_specific_params_nfcv_poll nfcv_poll;
} rf_tech_specific_params;
__u8 ntf_type;
@ -372,6 +381,7 @@ struct nci_rf_intf_activated_ntf {
struct rf_tech_specific_params_nfca_poll nfca_poll;
struct rf_tech_specific_params_nfcb_poll nfcb_poll;
struct rf_tech_specific_params_nfcf_poll nfcf_poll;
struct rf_tech_specific_params_nfcv_poll nfcv_poll;
} rf_tech_specific_params;
__u8 data_exch_rf_tech_and_mode;

View File

@ -64,10 +64,11 @@ enum nci_state {
struct nci_dev;
struct nci_ops {
int (*open)(struct nci_dev *ndev);
int (*close)(struct nci_dev *ndev);
int (*send)(struct nci_dev *ndev, struct sk_buff *skb);
int (*setup)(struct nci_dev *ndev);
int (*open)(struct nci_dev *ndev);
int (*close)(struct nci_dev *ndev);
int (*send)(struct nci_dev *ndev, struct sk_buff *skb);
int (*setup)(struct nci_dev *ndev);
__u32 (*get_rfprotocol)(struct nci_dev *ndev, __u8 rf_protocol);
};
#define NCI_MAX_SUPPORTED_RF_INTERFACES 4

View File

@ -33,6 +33,8 @@
#define DIGITAL_ATR_REQ_MAX_SIZE 64
#define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30
#define DIGITAL_FSL_BITS_PAYLOAD_SIZE_254B \
(DIGITAL_LR_BITS_PAYLOAD_SIZE_254B >> 4)
#define DIGITAL_GB_BIT 0x02
#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
@ -127,6 +129,98 @@ static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
return 0;
}
static void digital_in_recv_psl_res(struct nfc_digital_dev *ddev, void *arg,
struct sk_buff *resp)
{
struct nfc_target *target = arg;
struct digital_psl_res *psl_res;
int rc;
if (IS_ERR(resp)) {
rc = PTR_ERR(resp);
resp = NULL;
goto exit;
}
rc = ddev->skb_check_crc(resp);
if (rc) {
PROTOCOL_ERR("14.4.1.6");
goto exit;
}
rc = digital_skb_pull_dep_sod(ddev, resp);
if (rc) {
PROTOCOL_ERR("14.4.1.2");
goto exit;
}
psl_res = (struct digital_psl_res *)resp->data;
if ((resp->len != sizeof(*psl_res)) ||
(psl_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN) ||
(psl_res->cmd != DIGITAL_CMD_PSL_RES)) {
rc = -EIO;
goto exit;
}
rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
NFC_DIGITAL_RF_TECH_424F);
if (rc)
goto exit;
rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
NFC_DIGITAL_FRAMING_NFCF_NFC_DEP);
if (rc)
goto exit;
if (!DIGITAL_DRV_CAPS_IN_CRC(ddev) &&
(ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)) {
ddev->skb_add_crc = digital_skb_add_crc_f;
ddev->skb_check_crc = digital_skb_check_crc_f;
}
ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_424F;
nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
NFC_RF_INITIATOR);
ddev->curr_nfc_dep_pni = 0;
exit:
dev_kfree_skb(resp);
if (rc)
ddev->curr_protocol = 0;
}
static int digital_in_send_psl_req(struct nfc_digital_dev *ddev,
struct nfc_target *target)
{
struct sk_buff *skb;
struct digital_psl_req *psl_req;
skb = digital_skb_alloc(ddev, sizeof(*psl_req));
if (!skb)
return -ENOMEM;
skb_put(skb, sizeof(*psl_req));
psl_req = (struct digital_psl_req *)skb->data;
psl_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
psl_req->cmd = DIGITAL_CMD_PSL_REQ;
psl_req->did = 0;
psl_req->brs = (0x2 << 3) | 0x2; /* 424F both directions */
psl_req->fsl = DIGITAL_FSL_BITS_PAYLOAD_SIZE_254B;
digital_skb_push_dep_sod(ddev, skb);
ddev->skb_add_crc(skb);
return digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res,
target);
}
static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
struct sk_buff *resp)
{
@ -166,6 +260,13 @@ static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
if (rc)
goto exit;
if ((ddev->protocols & NFC_PROTO_FELICA_MASK) &&
(ddev->curr_rf_tech != NFC_DIGITAL_RF_TECH_424F)) {
rc = digital_in_send_psl_req(ddev, target);
if (!rc)
goto exit;
}
rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
NFC_RF_INITIATOR);

View File

@ -231,6 +231,14 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
cmd.num_disc_configs++;
}
if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
(protocols & NFC_PROTO_ISO15693_MASK)) {
cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
NCI_NFC_V_PASSIVE_POLL_MODE;
cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
cmd.num_disc_configs++;
}
nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD,
(1 + (cmd.num_disc_configs * sizeof(struct disc_config))),
&cmd);
@ -751,10 +759,6 @@ int nci_register_device(struct nci_dev *ndev)
struct device *dev = &ndev->nfc_dev->dev;
char name[32];
rc = nfc_register_device(ndev->nfc_dev);
if (rc)
goto exit;
ndev->flags = 0;
INIT_WORK(&ndev->cmd_work, nci_cmd_work);
@ -762,7 +766,7 @@ int nci_register_device(struct nci_dev *ndev)
ndev->cmd_wq = create_singlethread_workqueue(name);
if (!ndev->cmd_wq) {
rc = -ENOMEM;
goto unreg_exit;
goto exit;
}
INIT_WORK(&ndev->rx_work, nci_rx_work);
@ -792,6 +796,10 @@ int nci_register_device(struct nci_dev *ndev)
mutex_init(&ndev->req_lock);
rc = nfc_register_device(ndev->nfc_dev);
if (rc)
goto destroy_rx_wq_exit;
goto exit;
destroy_rx_wq_exit:
@ -800,9 +808,6 @@ int nci_register_device(struct nci_dev *ndev)
destroy_cmd_wq_exit:
destroy_workqueue(ndev->cmd_wq);
unreg_exit:
nfc_unregister_device(ndev->nfc_dev);
exit:
return rc;
}

View File

@ -241,9 +241,12 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
/* strip the nci data header */
skb_pull(skb, NCI_DATA_HDR_SIZE);
if (ndev->target_active_prot == NFC_PROTO_MIFARE) {
if (ndev->target_active_prot == NFC_PROTO_MIFARE ||
ndev->target_active_prot == NFC_PROTO_JEWEL ||
ndev->target_active_prot == NFC_PROTO_FELICA ||
ndev->target_active_prot == NFC_PROTO_ISO15693) {
/* frame I/F => remove the status byte */
pr_debug("NFC_PROTO_MIFARE => remove the status byte\n");
pr_debug("frame I/F => remove the status byte\n");
skb_trim(skb, (skb->len - 1));
}

View File

@ -2,6 +2,7 @@
* The NFC Controller Interface is the communication protocol between an
* NFC Controller (NFCC) and a Device Host (DH).
*
* Copyright (C) 2014 Marvell International Ltd.
* Copyright (C) 2011 Texas Instruments, Inc.
*
* Written by Ilan Elias <ilane@ti.com>
@ -155,6 +156,24 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
return data;
}
static __u8 *nci_extract_rf_params_nfcv_passive_poll(struct nci_dev *ndev,
struct rf_tech_specific_params_nfcv_poll *nfcv_poll,
__u8 *data)
{
++data;
nfcv_poll->dsfid = *data++;
memcpy(nfcv_poll->uid, data, NFC_ISO15693_UID_MAXSIZE);
data += NFC_ISO15693_UID_MAXSIZE;
return data;
}
__u32 nci_get_prop_rf_protocol(struct nci_dev *ndev, __u8 rf_protocol)
{
if (ndev->ops->get_rfprotocol)
return ndev->ops->get_rfprotocol(ndev, rf_protocol);
return 0;
}
static int nci_add_new_protocol(struct nci_dev *ndev,
struct nfc_target *target,
__u8 rf_protocol,
@ -164,6 +183,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
struct rf_tech_specific_params_nfca_poll *nfca_poll;
struct rf_tech_specific_params_nfcb_poll *nfcb_poll;
struct rf_tech_specific_params_nfcf_poll *nfcf_poll;
struct rf_tech_specific_params_nfcv_poll *nfcv_poll;
__u32 protocol;
if (rf_protocol == NCI_RF_PROTOCOL_T1T)
@ -179,8 +199,10 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
protocol = NFC_PROTO_FELICA_MASK;
else if (rf_protocol == NCI_RF_PROTOCOL_NFC_DEP)
protocol = NFC_PROTO_NFC_DEP_MASK;
else if (rf_protocol == NCI_RF_PROTOCOL_T5T)
protocol = NFC_PROTO_ISO15693_MASK;
else
protocol = 0;
protocol = nci_get_prop_rf_protocol(ndev, rf_protocol);
if (!(protocol & ndev->poll_prots)) {
pr_err("the target found does not have the desired protocol\n");
@ -213,6 +235,12 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
memcpy(target->sensf_res, nfcf_poll->sensf_res,
target->sensf_res_len);
}
} else if (rf_tech_and_mode == NCI_NFC_V_PASSIVE_POLL_MODE) {
nfcv_poll = (struct rf_tech_specific_params_nfcv_poll *)params;
target->is_iso15693 = 1;
target->iso15693_dsfid = nfcv_poll->dsfid;
memcpy(target->iso15693_uid, nfcv_poll->uid, NFC_ISO15693_UID_MAXSIZE);
} else {
pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode);
return -EPROTO;
@ -305,6 +333,11 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
&(ntf.rf_tech_specific_params.nfcf_poll), data);
break;
case NCI_NFC_V_PASSIVE_POLL_MODE:
data = nci_extract_rf_params_nfcv_passive_poll(ndev,
&(ntf.rf_tech_specific_params.nfcv_poll), data);
break;
default:
pr_err("unsupported rf_tech_and_mode 0x%x\n",
ntf.rf_tech_and_mode);
@ -455,6 +488,11 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
&(ntf.rf_tech_specific_params.nfcf_poll), data);
break;
case NCI_NFC_V_PASSIVE_POLL_MODE:
data = nci_extract_rf_params_nfcv_passive_poll(ndev,
&(ntf.rf_tech_specific_params.nfcv_poll), data);
break;
default:
pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
ntf.activation_rf_tech_and_mode);