mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-28 15:13:55 +08:00
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:
commit
330bd4ec9d
@ -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>;
|
||||
};
|
||||
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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_ */
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -42,6 +42,10 @@ struct llt_ndlc {
|
||||
|
||||
struct device *dev;
|
||||
|
||||
/*
|
||||
* < 0 if hardware error occured
|
||||
* and prevents normal operation.
|
||||
*/
|
||||
int hard_fault;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 @@ destroy_rx_wq_exit:
|
||||
destroy_cmd_wq_exit:
|
||||
destroy_workqueue(ndev->cmd_wq);
|
||||
|
||||
unreg_exit:
|
||||
nfc_unregister_device(ndev->nfc_dev);
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user