Commit 330bd4ec authored by John W. Linville's avatar John W. Linville

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: default avatarJohn W. Linville <linville@tuxdriver.com>
parents 687b9308 094e9359
...@@ -26,7 +26,7 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on I2C2): ...@@ -26,7 +26,7 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on I2C2):
clock-frequency = <400000>; clock-frequency = <400000>;
interrupt-parent = <&gpio5>; interrupt-parent = <&gpio5>;
interrupts = <2 IRQ_TYPE_LEVEL_LOW>; interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
reset-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
}; };
......
...@@ -13,6 +13,11 @@ Optional SoC Specific Properties: ...@@ -13,6 +13,11 @@ Optional SoC Specific Properties:
- pinctrl-names: Contains only one value - "default". - pinctrl-names: Contains only one value - "default".
- pintctrl-0: Specifies the pin control groups used for this controller. - pintctrl-0: Specifies the pin control groups used for this controller.
- autosuspend-delay: Specify autosuspend delay in milliseconds. - 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): Example (for ARM-based BeagleBone with TRF7970A on SPI1):
...@@ -30,7 +35,10 @@ 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>, ti,enable-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>,
<&gpio2 5 GPIO_ACTIVE_LOW>; <&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>; vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
autosuspend-delay = <30000>; autosuspend-delay = <30000>;
irq-status-read-quirk;
en2-rf-quirk;
status = "okay"; status = "okay";
}; };
}; };
...@@ -271,6 +271,7 @@ static int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb) ...@@ -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) static int get_frame_size(u8 *buf, int buflen)
{ {
int len = 0; int len = 0;
if (buf[len + 1] == ST21NFCA_SOF_EOF) if (buf[len + 1] == ST21NFCA_SOF_EOF)
return 0; return 0;
...@@ -311,6 +312,7 @@ static int check_crc(u8 *buf, int buflen) ...@@ -311,6 +312,7 @@ static int check_crc(u8 *buf, int buflen)
static int st21nfca_hci_i2c_repack(struct sk_buff *skb) static int st21nfca_hci_i2c_repack(struct sk_buff *skb)
{ {
int i, j, r, size; int i, j, r, size;
if (skb->len < 1 || (skb->len > 1 && skb->data[1] != 0)) if (skb->len < 1 || (skb->len > 1 && skb->data[1] != 0))
return -EBADMSG; return -EBADMSG;
...@@ -525,24 +527,19 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) ...@@ -525,24 +527,19 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client)
} }
/* GPIO request and configuration */ /* 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) { if (r) {
nfc_err(&client->dev, "Failed to request enable pin\n"); nfc_err(&client->dev, "Failed to request enable pin\n");
return -ENODEV; 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; phy->gpio_ena = gpio;
/* IRQ */ /* IRQ */
r = irq_of_parse_and_map(pp, 0); r = irq_of_parse_and_map(pp, 0);
if (r < 0) { if (r < 0) {
nfc_err(&client->dev, nfc_err(&client->dev, "Unable to get irq, error: %d\n", r);
"Unable to get irq, error: %d\n", r);
return r; return r;
} }
...@@ -576,32 +573,20 @@ static int st21nfca_hci_i2c_request_resources(struct i2c_client *client) ...@@ -576,32 +573,20 @@ static int st21nfca_hci_i2c_request_resources(struct i2c_client *client)
phy->gpio_ena = pdata->gpio_ena; phy->gpio_ena = pdata->gpio_ena;
phy->irq_polarity = pdata->irq_polarity; 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) { if (r) {
pr_err("%s : gpio_request failed\n", __FILE__); pr_err("%s : gpio_request failed\n", __FILE__);
return -ENODEV; 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) { if (phy->gpio_ena > 0) {
r = devm_gpio_request(&client->dev, r = devm_gpio_request_one(&client->dev, phy->gpio_ena,
phy->gpio_ena, "clf_enable"); GPIOF_OUT_INIT_HIGH, "clf_enable");
if (r) { if (r) {
pr_err("%s : ena gpio_request failed\n", __FILE__); pr_err("%s : ena gpio_request failed\n", __FILE__);
return -ENODEV; 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 */ /* IRQ */
...@@ -711,7 +696,6 @@ static struct i2c_driver st21nfca_hci_i2c_driver = { ...@@ -711,7 +696,6 @@ static struct i2c_driver st21nfca_hci_i2c_driver = {
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = ST21NFCA_HCI_I2C_DRIVER_NAME, .name = ST21NFCA_HCI_I2C_DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_st21nfca_i2c_match), .of_match_table = of_match_ptr(of_st21nfca_i2c_match),
}, },
.probe = st21nfca_hci_i2c_probe, .probe = st21nfca_hci_i2c_probe,
......
...@@ -45,6 +45,23 @@ ...@@ -45,6 +45,23 @@
#define ST21NFCA_RF_READER_14443_3_A_ATQA 0x03 #define ST21NFCA_RF_READER_14443_3_A_ATQA 0x03
#define ST21NFCA_RF_READER_14443_3_A_SAK 0x04 #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_GATE 0x01
#define ST21NFCA_DEVICE_MGNT_PIPE 0x02 #define ST21NFCA_DEVICE_MGNT_PIPE 0x02
...@@ -60,6 +77,10 @@ ...@@ -60,6 +77,10 @@
((p & 0x0f) == (ST21NFCA_DM_PIPE_CREATED | ST21NFCA_DM_PIPE_OPEN)) ((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); static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES);
...@@ -355,8 +376,8 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev, ...@@ -355,8 +376,8 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
if (r < 0) if (r < 0)
return r; return r;
pol_req = pol_req = be32_to_cpu((__force __be32)
be32_to_cpu(ST21NFCA_RF_READER_F_POL_REQ_DEFAULT); ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE, r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
ST21NFCA_RF_READER_F_POL_REQ, ST21NFCA_RF_READER_F_POL_REQ,
(u8 *) &pol_req, 4); (u8 *) &pol_req, 4);
...@@ -790,6 +811,7 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev, ...@@ -790,6 +811,7 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
struct nfc_target *target) struct nfc_target *target)
{ {
u8 fwi = 0x11; u8 fwi = 0x11;
switch (target->hci_reader_gate) { switch (target->hci_reader_gate) {
case NFC_HCI_RF_READER_A_GATE: case NFC_HCI_RF_READER_A_GATE:
case NFC_HCI_RF_READER_B_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, ...@@ -839,20 +861,16 @@ static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate,
if (gate == ST21NFCA_RF_CARD_F_GATE) { if (gate == ST21NFCA_RF_CARD_F_GATE) {
r = st21nfca_tm_event_send_data(hdev, skb, gate); r = st21nfca_tm_event_send_data(hdev, skb, gate);
if (r < 0) if (r < 0)
goto exit; return r;
return 0; return 0;
} else { }
info->dep_info.curr_nfc_dep_pni = 0; info->dep_info.curr_nfc_dep_pni = 0;
return 1; return 1;
}
break;
default: default:
return 1; return 1;
} }
kfree_skb(skb); kfree_skb(skb);
return 0; return 0;
exit:
return r;
} }
static struct nfc_hci_ops st21nfca_hci_ops = { 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, ...@@ -904,8 +922,11 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
* persistent info to discriminate 2 identical chips * persistent info to discriminate 2 identical chips
*/ */
dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES); dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES);
if (dev_num >= 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", scnprintf(init_data.session_id, sizeof(init_data.session_id), "%s%2x",
"ST21AH", dev_num); "ST21AH", dev_num);
......
...@@ -82,30 +82,9 @@ struct st21nfca_hci_info { ...@@ -82,30 +82,9 @@ struct st21nfca_hci_info {
#define ST21NFCA_WR_XCHG_DATA 0x10 #define ST21NFCA_WR_XCHG_DATA 0x10
#define ST21NFCA_RF_READER_F_GATE 0x14 #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_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_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_ */ #endif /* __LOCAL_ST21NFCA_H_ */
...@@ -121,6 +121,7 @@ static void st21nfca_tx_work(struct work_struct *work) ...@@ -121,6 +121,7 @@ static void st21nfca_tx_work(struct work_struct *work)
struct nfc_dev *dev; struct nfc_dev *dev;
struct sk_buff *skb; struct sk_buff *skb;
if (info) { if (info) {
dev = info->hdev->ndev; dev = info->hdev->ndev;
skb = info->dep_info.tx_pending; skb = info->dep_info.tx_pending;
...@@ -128,8 +129,7 @@ static void st21nfca_tx_work(struct work_struct *work) ...@@ -128,8 +129,7 @@ static void st21nfca_tx_work(struct work_struct *work)
device_lock(&dev->dev); device_lock(&dev->dev);
nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE, nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
ST21NFCA_WR_XCHG_DATA, ST21NFCA_WR_XCHG_DATA, skb->data, skb->len,
skb->data, skb->len,
info->async_cb, info); info->async_cb, info);
device_unlock(&dev->dev); device_unlock(&dev->dev);
kfree_skb(skb); kfree_skb(skb);
...@@ -185,8 +185,10 @@ static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev, ...@@ -185,8 +185,10 @@ static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
info->dep_info.curr_nfc_dep_pni = 0; 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); 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, 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, ...@@ -197,10 +199,6 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
int r; int r;
skb_trim(skb, skb->len - 1); skb_trim(skb, skb->len - 1);
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
goto exit;
}
if (!skb->len) { if (!skb->len) {
r = -EIO; r = -EIO;
...@@ -214,6 +212,11 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev, ...@@ -214,6 +212,11 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
atr_req = (struct st21nfca_atr_req *)skb->data; 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); r = st21nfca_tm_send_atr_res(hdev, atr_req);
if (r) if (r)
goto exit; goto exit;
...@@ -237,7 +240,6 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev, ...@@ -237,7 +240,6 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
struct st21nfca_psl_res *psl_res; struct st21nfca_psl_res *psl_res;
struct sk_buff *skb; struct sk_buff *skb;
u8 bitrate[2] = {0, 0}; u8 bitrate[2] = {0, 0};
int r; int r;
skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL); 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, ...@@ -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, 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);
if (r < 0)
goto error;
/* /*
* ST21NFCA only support P2P passive. * ST21NFCA only support P2P passive.
...@@ -269,8 +273,11 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev, ...@@ -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 */ /* 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); 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, 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, ...@@ -280,11 +287,6 @@ static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
int r; int r;
skb_trim(skb, skb->len - 1); skb_trim(skb, skb->len - 1);
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
skb = NULL;
goto exit;
}
if (!skb->len) { if (!skb->len) {
r = -EIO; r = -EIO;
...@@ -330,11 +332,6 @@ static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev, ...@@ -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); struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
skb_trim(skb, skb->len - 1); skb_trim(skb, skb->len - 1);
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
skb = NULL;
goto exit;
}
size = 4; size = 4;
...@@ -368,12 +365,6 @@ static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev, ...@@ -368,12 +365,6 @@ static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
break; break;
} }
if (IS_ERR(skb)) {
r = PTR_ERR(skb);
skb = NULL;
goto exit;
}
skb_pull(skb, size); skb_pull(skb, size);
return nfc_tm_data_received(hdev->ndev, skb); 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, ...@@ -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; *skb_push(skb, 1) = info->dep_info.to | 0x10;
st21nfca_im_send_pdu(info, skb); st21nfca_im_send_pdu(info, skb);
kfree_skb(skb);
} }
#define ST21NFCA_CB_TYPE_READER_F 1 #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, ...@@ -452,7 +441,7 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
if (err != 0) if (err != 0)
return; return;
if (IS_ERR(skb)) if (!skb)
return; return;
switch (info->async_cb_type) { switch (info->async_cb_type) {
...@@ -484,7 +473,6 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb, ...@@ -484,7 +473,6 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
ST21NFCA_PP2LRI(atr_res->ppi)); ST21NFCA_PP2LRI(atr_res->ppi));
break; break;
default: default:
if (err == 0)
kfree_skb(skb); kfree_skb(skb);
break; break;
} }
...@@ -522,7 +510,7 @@ int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len) ...@@ -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); memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
target = hdev->ndev->targets; target = hdev->ndev->targets;
if (target->sensf_res) if (target->sensf_res_len > 0)
memcpy(atr_req->nfcid3, target->sensf_res, memcpy(atr_req->nfcid3, target->sensf_res,
target->sensf_res_len); target->sensf_res_len);
else else
...@@ -565,7 +553,7 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb, ...@@ -565,7 +553,7 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
if (err != 0) if (err != 0)
return; return;
if (IS_ERR(skb)) if (!skb)
return; return;
switch (info->async_cb_type) { switch (info->async_cb_type) {
...@@ -615,7 +603,6 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb, ...@@ -615,7 +603,6 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
} }
exit: exit:
if (err == 0)
kfree_skb(skb); kfree_skb(skb);
} }
......
...@@ -17,24 +17,16 @@ ...@@ -17,24 +17,16 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/crc-ccitt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/firmware.h>
#include <linux/unaligned/access_ok.h>
#include <linux/platform_data/st21nfcb.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" #include "ndlc.h"
#define DRIVER_DESC "NCI NFC driver for ST21NFCB" #define DRIVER_DESC "NCI NFC driver for ST21NFCB"
...@@ -63,12 +55,6 @@ struct st21nfcb_i2c_phy { ...@@ -63,12 +55,6 @@ struct st21nfcb_i2c_phy {
unsigned int irq_polarity; unsigned int irq_polarity;
int powered; int powered;
/*
* < 0 if hardware error occured (e.g. i2c err)
* and prevents normal operation.
*/
int hard_fault;
}; };
#define I2C_DUMP_SKB(info, skb) \ #define I2C_DUMP_SKB(info, skb) \
...@@ -122,8 +108,8 @@ static int st21nfcb_nci_i2c_write(void *phy_id, struct sk_buff *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); I2C_DUMP_SKB("st21nfcb_nci_i2c_write", skb);
if (phy->hard_fault != 0) if (phy->ndlc->hard_fault != 0)
return phy->hard_fault; return phy->ndlc->hard_fault;
r = i2c_master_send(client, skb->data, skb->len); r = i2c_master_send(client, skb->data, skb->len);
if (r == -EREMOTEIO) { /* Retry, chip was in standby */ if (r == -EREMOTEIO) { /* Retry, chip was in standby */
...@@ -168,11 +154,11 @@ static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy, ...@@ -168,11 +154,11 @@ static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy,
if (r == -EREMOTEIO) { /* Retry, chip was in standby */ if (r == -EREMOTEIO) { /* Retry, chip was in standby */
usleep_range(1000, 4000); usleep_range(1000, 4000);
r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE); 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)); len = be16_to_cpu(*(__be16 *) (buf + 2));
if (len > ST21NFCB_NCI_I2C_MAX_SIZE) { if (len > ST21NFCB_NCI_I2C_MAX_SIZE) {
nfc_err(&client->dev, "invalid frame len\n"); 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) ...@@ -224,7 +210,7 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id)
client = phy->i2c_dev; client = phy->i2c_dev;
dev_dbg(&client->dev, "IRQ\n"); dev_dbg(&client->dev, "IRQ\n");
if (phy->hard_fault) if (phy->ndlc->hard_fault)
return IRQ_HANDLED; return IRQ_HANDLED;
if (!phy->powered) { if (!phy->powered) {
...@@ -233,13 +219,8 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id) ...@@ -233,13 +219,8 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id)
} }
r = st21nfcb_nci_i2c_read(phy, &skb); r = st21nfcb_nci_i2c_read(phy, &skb);
if (r == -EREMOTEIO) { if (r == -EREMOTEIO || r == -ENOMEM || r == -EBADMSG)
phy->hard_fault = r;
ndlc_recv(phy->ndlc, NULL);
return IRQ_HANDLED; return IRQ_HANDLED;
} else if (r == -ENOMEM || r == -EBADMSG) {
return IRQ_HANDLED;
}
ndlc_recv(phy->ndlc, skb); ndlc_recv(phy->ndlc, skb);
...@@ -273,25 +254,18 @@ static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client) ...@@ -273,25 +254,18 @@ static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client)
} }
/* GPIO request and configuration */ /* 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) { if (r) {
nfc_err(&client->dev, "Failed to request reset pin\n"); nfc_err(&client->dev, "Failed to request reset pin\n");
return -ENODEV; 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; phy->gpio_reset = gpio;
/* IRQ */ /* IRQ */
r = irq_of_parse_and_map(pp, 0); r = irq_of_parse_and_map(pp, 0);
if (r < 0) { if (r < 0) {
nfc_err(&client->dev, nfc_err(&client->dev, "Unable to get irq, error: %d\n", r);
"Unable to get irq, error: %d\n", r);
return r; return r;
} }
...@@ -325,32 +299,20 @@ static int st21nfcb_nci_i2c_request_resources(struct i2c_client *client) ...@@ -325,32 +299,20 @@ static int st21nfcb_nci_i2c_request_resources(struct i2c_client *client)
phy->gpio_reset = pdata->gpio_reset; phy->gpio_reset = pdata->gpio_reset;
phy->irq_polarity = pdata->irq_polarity; 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) { if (r) {
pr_err("%s : gpio_request failed\n", __FILE__); pr_err("%s : gpio_request failed\n", __FILE__);
return -ENODEV; return -ENODEV;
} }
r = gpio_direction_input(phy->gpio_irq); r = devm_gpio_request_one(&client->dev,
if (r) { phy->gpio_reset, GPIOF_OUT_INIT_HIGH, "clf_reset");
pr_err("%s : gpio_direction_input failed\n", __FILE__);
return -ENODEV;
}
r = devm_gpio_request(&client->dev,
phy->gpio_reset, "clf_reset");
if (r) { if (r) {
pr_err("%s : reset gpio_request failed\n", __FILE__); pr_err("%s : reset gpio_request failed\n", __FILE__);
return -ENODEV; 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 */
irq = gpio_to_irq(phy->gpio_irq); irq = gpio_to_irq(phy->gpio_irq);
if (irq < 0) { if (irq < 0) {
...@@ -448,7 +410,6 @@ static struct i2c_driver st21nfcb_nci_i2c_driver = { ...@@ -448,7 +410,6 @@ static struct i2c_driver st21nfcb_nci_i2c_driver = {
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = ST21NFCB_NCI_I2C_DRIVER_NAME, .name = ST21NFCB_NCI_I2C_DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_st21nfcb_i2c_match), .of_match_table = of_match_ptr(of_st21nfcb_i2c_match),
}, },
.probe = st21nfcb_nci_i2c_probe, .probe = st21nfcb_nci_i2c_probe,
......
...@@ -112,6 +112,10 @@ static void llt_ndlc_send_queue(struct llt_ndlc *ndlc) ...@@ -112,6 +112,10 @@ static void llt_ndlc_send_queue(struct llt_ndlc *ndlc)
ndlc->t1_active = true; ndlc->t1_active = true;
mod_timer(&ndlc->t1_timer, time_sent + mod_timer(&ndlc->t1_timer, time_sent +
msecs_to_jiffies(NDLC_TIMER_T1)); 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) ...@@ -207,7 +211,7 @@ static void llt_ndlc_sm_work(struct work_struct *work)
ndlc->t2_active = false; ndlc->t2_active = false;
ndlc->t1_active = false; ndlc->t1_active = false;
del_timer_sync(&ndlc->t1_timer); del_timer_sync(&ndlc->t1_timer);
del_timer_sync(&ndlc->t2_timer);
ndlc_close(ndlc); ndlc_close(ndlc);
ndlc->hard_fault = -EREMOTEIO; ndlc->hard_fault = -EREMOTEIO;
} }
......
...@@ -42,6 +42,10 @@ struct llt_ndlc { ...@@ -42,6 +42,10 @@ struct llt_ndlc {
struct device *dev; struct device *dev;
/*
* < 0 if hardware error occured
* and prevents normal operation.
*/
int hard_fault; int hard_fault;
}; };
......
...@@ -22,10 +22,11 @@ ...@@ -22,10 +22,11 @@
#include <net/nfc/nci_core.h> #include <net/nfc/nci_core.h>
#include "st21nfcb.h" #include "st21nfcb.h"
#include "ndlc.h"
#define DRIVER_DESC "NCI NFC driver for ST21NFCB" #define DRIVER_DESC "NCI NFC driver for ST21NFCB"
#define ST21NFCB_NCI1_X_PROPRIETARY_ISO15693 0x83
static int st21nfcb_nci_open(struct nci_dev *ndev) static int st21nfcb_nci_open(struct nci_dev *ndev)
{ {
struct st21nfcb_nci_info *info = nci_get_drvdata(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) ...@@ -65,10 +66,18 @@ static int st21nfcb_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
return ndlc_send(info->ndlc, 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 = { static struct nci_ops st21nfcb_nci_ops = {
.open = st21nfcb_nci_open, .open = st21nfcb_nci_open,
.close = st21nfcb_nci_close, .close = st21nfcb_nci_close,
.send = st21nfcb_nci_send, .send = st21nfcb_nci_send,
.get_rfprotocol = st21nfcb_nci_get_rfprotocol,
}; };
int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom,
...@@ -88,29 +97,25 @@ int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, ...@@ -88,29 +97,25 @@ int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom,
| NFC_PROTO_FELICA_MASK | NFC_PROTO_FELICA_MASK
| NFC_PROTO_ISO14443_MASK | NFC_PROTO_ISO14443_MASK
| NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_ISO14443_B_MASK
| NFC_PROTO_ISO15693_MASK
| NFC_PROTO_NFC_DEP_MASK; | NFC_PROTO_NFC_DEP_MASK;
ndlc->ndev = nci_allocate_device(&st21nfcb_nci_ops, protocols, ndlc->ndev = nci_allocate_device(&st21nfcb_nci_ops, protocols,
phy_headroom, phy_tailroom); phy_headroom, phy_tailroom);
if (!ndlc->ndev) { if (!ndlc->ndev) {
pr_err("Cannot allocate nfc ndev\n"); pr_err("Cannot allocate nfc ndev\n");
r = -ENOMEM; return -ENOMEM;
goto err_alloc_ndev;
} }
info->ndlc = ndlc; info->ndlc = ndlc;
nci_set_drvdata(ndlc->ndev, info); nci_set_drvdata(ndlc->ndev, info);
r = nci_register_device(ndlc->ndev); r = nci_register_device(ndlc->ndev);
if (r) if (r) {
goto err_regdev; pr_err("Cannot register nfc device to nci core\n");
return r;
err_regdev:
nci_free_device(ndlc->ndev); nci_free_device(ndlc->ndev);
}
err_alloc_ndev:
kfree(info);
return r; return r;
} }
EXPORT_SYMBOL_GPL(st21nfcb_nci_probe); EXPORT_SYMBOL_GPL(st21nfcb_nci_probe);
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
#ifndef __LOCAL_ST21NFCB_H_ #ifndef __LOCAL_ST21NFCB_H_
#define __LOCAL_ST21NFCB_H_ #define __LOCAL_ST21NFCB_H_
#include <net/nfc/nci_core.h>
#include "ndlc.h" #include "ndlc.h"
/* Define private flags: */ /* Define private flags: */
......
This diff is collapsed.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* The NFC Controller Interface is the communication protocol between an * The NFC Controller Interface is the communication protocol between an
* NFC Controller (NFCC) and a Device Host (DH). * NFC Controller (NFCC) and a Device Host (DH).
* *
* Copyright (C) 2014 Marvell International Ltd.
* Copyright (C) 2011 Texas Instruments, Inc. * Copyright (C) 2011 Texas Instruments, Inc.
* *
* Written by Ilan Elias <ilane@ti.com> * Written by Ilan Elias <ilane@ti.com>
...@@ -65,19 +66,18 @@ ...@@ -65,19 +66,18 @@
#define NCI_NFC_F_PASSIVE_POLL_MODE 0x02 #define NCI_NFC_F_PASSIVE_POLL_MODE 0x02
#define NCI_NFC_A_ACTIVE_POLL_MODE 0x03 #define NCI_NFC_A_ACTIVE_POLL_MODE 0x03
#define NCI_NFC_F_ACTIVE_POLL_MODE 0x05 #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_A_PASSIVE_LISTEN_MODE 0x80
#define NCI_NFC_B_PASSIVE_LISTEN_MODE 0x81 #define NCI_NFC_B_PASSIVE_LISTEN_MODE 0x81
#define NCI_NFC_F_PASSIVE_LISTEN_MODE 0x82 #define NCI_NFC_F_PASSIVE_LISTEN_MODE 0x82
#define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83 #define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83
#define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85 #define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85
#define NCI_NFC_15693_PASSIVE_LISTEN_MODE 0x86
/* NCI RF Technologies */ /* NCI RF Technologies */
#define NCI_NFC_RF_TECHNOLOGY_A 0x00 #define NCI_NFC_RF_TECHNOLOGY_A 0x00
#define NCI_NFC_RF_TECHNOLOGY_B 0x01 #define NCI_NFC_RF_TECHNOLOGY_B 0x01
#define NCI_NFC_RF_TECHNOLOGY_F 0x02 #define NCI_NFC_RF_TECHNOLOGY_F 0x02
#define NCI_NFC_RF_TECHNOLOGY_15693 0x03 #define NCI_NFC_RF_TECHNOLOGY_V 0x03
/* NCI Bit Rates */ /* NCI Bit Rates */
#define NCI_NFC_BIT_RATE_106 0x00 #define NCI_NFC_BIT_RATE_106 0x00
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
#define NCI_NFC_BIT_RATE_1695 0x04 #define NCI_NFC_BIT_RATE_1695 0x04
#define NCI_NFC_BIT_RATE_3390 0x05 #define NCI_NFC_BIT_RATE_3390 0x05
#define NCI_NFC_BIT_RATE_6780 0x06 #define NCI_NFC_BIT_RATE_6780 0x06
#define NCI_NFC_BIT_RATE_26 0x20
/* NCI RF Protocols */ /* NCI RF Protocols */
#define NCI_RF_PROTOCOL_UNKNOWN 0x00 #define NCI_RF_PROTOCOL_UNKNOWN 0x00
...@@ -95,6 +96,7 @@ ...@@ -95,6 +96,7 @@
#define NCI_RF_PROTOCOL_T3T 0x03 #define NCI_RF_PROTOCOL_T3T 0x03
#define NCI_RF_PROTOCOL_ISO_DEP 0x04 #define NCI_RF_PROTOCOL_ISO_DEP 0x04
#define NCI_RF_PROTOCOL_NFC_DEP 0x05 #define NCI_RF_PROTOCOL_NFC_DEP 0x05
#define NCI_RF_PROTOCOL_T5T 0x06
/* NCI RF Interfaces */ /* NCI RF Interfaces */
#define NCI_RF_INTERFACE_NFCEE_DIRECT 0x00 #define NCI_RF_INTERFACE_NFCEE_DIRECT 0x00
...@@ -328,6 +330,12 @@ struct rf_tech_specific_params_nfcf_poll { ...@@ -328,6 +330,12 @@ struct rf_tech_specific_params_nfcf_poll {
__u8 sensf_res[18]; /* 16 or 18 Bytes */ __u8 sensf_res[18]; /* 16 or 18 Bytes */
} __packed; } __packed;
struct rf_tech_specific_params_nfcv_poll {
__u8 res_flags;
__u8 dsfid;
__u8 uid[8]; /* 8 Bytes */
} __packed;
struct nci_rf_discover_ntf { struct nci_rf_discover_ntf {
__u8 rf_discovery_id; __u8 rf_discovery_id;
__u8 rf_protocol; __u8 rf_protocol;
...@@ -338,6 +346,7 @@ struct nci_rf_discover_ntf { ...@@ -338,6 +346,7 @@ struct nci_rf_discover_ntf {
struct rf_tech_specific_params_nfca_poll nfca_poll; struct rf_tech_specific_params_nfca_poll nfca_poll;
struct rf_tech_specific_params_nfcb_poll nfcb_poll; struct rf_tech_specific_params_nfcb_poll nfcb_poll;
struct rf_tech_specific_params_nfcf_poll nfcf_poll; struct rf_tech_specific_params_nfcf_poll nfcf_poll;
struct rf_tech_specific_params_nfcv_poll nfcv_poll;
} rf_tech_specific_params; } rf_tech_specific_params;
__u8 ntf_type; __u8 ntf_type;
...@@ -372,6 +381,7 @@ struct nci_rf_intf_activated_ntf { ...@@ -372,6 +381,7 @@ struct nci_rf_intf_activated_ntf {
struct rf_tech_specific_params_nfca_poll nfca_poll; struct rf_tech_specific_params_nfca_poll nfca_poll;
struct rf_tech_specific_params_nfcb_poll nfcb_poll; struct rf_tech_specific_params_nfcb_poll nfcb_poll;
struct rf_tech_specific_params_nfcf_poll nfcf_poll; struct rf_tech_specific_params_nfcf_poll nfcf_poll;
struct rf_tech_specific_params_nfcv_poll nfcv_poll;
} rf_tech_specific_params; } rf_tech_specific_params;
__u8 data_exch_rf_tech_and_mode; __u8 data_exch_rf_tech_and_mode;
......
...@@ -68,6 +68,7 @@ struct nci_ops { ...@@ -68,6 +68,7 @@ struct nci_ops {
int (*close)(struct nci_dev *ndev); int (*close)(struct nci_dev *ndev);
int (*send)(struct nci_dev *ndev, struct sk_buff *skb); int (*send)(struct nci_dev *ndev, struct sk_buff *skb);
int (*setup)(struct nci_dev *ndev); int (*setup)(struct nci_dev *ndev);
__u32 (*get_rfprotocol)(struct nci_dev *ndev, __u8 rf_protocol);
}; };
#define NCI_MAX_SUPPORTED_RF_INTERFACES 4 #define NCI_MAX_SUPPORTED_RF_INTERFACES 4
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define DIGITAL_ATR_REQ_MAX_SIZE 64 #define DIGITAL_ATR_REQ_MAX_SIZE 64
#define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30 #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_GB_BIT 0x02
#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0) #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, ...@@ -127,6 +129,98 @@ static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
return 0; 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, static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
struct sk_buff *resp) struct sk_buff *resp)
{ {
...@@ -166,6 +260,13 @@ static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg, ...@@ -166,6 +260,13 @@ static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
if (rc) if (rc)
goto exit; 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, rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
NFC_RF_INITIATOR); NFC_RF_INITIATOR);
......
...@@ -231,6 +231,14 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) ...@@ -231,6 +231,14 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
cmd.num_disc_configs++; 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, nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD,
(1 + (cmd.num_disc_configs * sizeof(struct disc_config))), (1 + (cmd.num_disc_configs * sizeof(struct disc_config))),
&cmd); &cmd);
...@@ -751,10 +759,6 @@ int nci_register_device(struct nci_dev *ndev) ...@@ -751,10 +759,6 @@ int nci_register_device(struct nci_dev *ndev)
struct device *dev = &ndev->nfc_dev->dev; struct device *dev = &ndev->nfc_dev->dev;
char name[32]; char name[32];
rc = nfc_register_device(ndev->nfc_dev);
if (rc)
goto exit;
ndev->flags = 0; ndev->flags = 0;
INIT_WORK(&ndev->cmd_work, nci_cmd_work); INIT_WORK(&ndev->cmd_work, nci_cmd_work);
...@@ -762,7 +766,7 @@ int nci_register_device(struct nci_dev *ndev) ...@@ -762,7 +766,7 @@ int nci_register_device(struct nci_dev *ndev)
ndev->cmd_wq = create_singlethread_workqueue(name); ndev->cmd_wq = create_singlethread_workqueue(name);
if (!ndev->cmd_wq) { if (!ndev->cmd_wq) {
rc = -ENOMEM; rc = -ENOMEM;
goto unreg_exit; goto exit;
} }
INIT_WORK(&ndev->rx_work, nci_rx_work); INIT_WORK(&ndev->rx_work, nci_rx_work);
...@@ -792,6 +796,10 @@ int nci_register_device(struct nci_dev *ndev) ...@@ -792,6 +796,10 @@ int nci_register_device(struct nci_dev *ndev)
mutex_init(&ndev->req_lock); mutex_init(&ndev->req_lock);
rc = nfc_register_device(ndev->nfc_dev);
if (rc)
goto destroy_rx_wq_exit;
goto exit; goto exit;
destroy_rx_wq_exit: destroy_rx_wq_exit:
...@@ -800,9 +808,6 @@ int nci_register_device(struct nci_dev *ndev) ...@@ -800,9 +808,6 @@ int nci_register_device(struct nci_dev *ndev)
destroy_cmd_wq_exit: destroy_cmd_wq_exit:
destroy_workqueue(ndev->cmd_wq); destroy_workqueue(ndev->cmd_wq);
unreg_exit:
nfc_unregister_device(ndev->nfc_dev);
exit: exit:
return rc; return rc;
} }
......
...@@ -241,9 +241,12 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) ...@@ -241,9 +241,12 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
/* strip the nci data header */ /* strip the nci data header */
skb_pull(skb, NCI_DATA_HDR_SIZE); 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 */ /* 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)); skb_trim(skb, (skb->len - 1));
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* The NFC Controller Interface is the communication protocol between an * The NFC Controller Interface is the communication protocol between an
* NFC Controller (NFCC) and a Device Host (DH). * NFC Controller (NFCC) and a Device Host (DH).
* *
* Copyright (C) 2014 Marvell International Ltd.
* Copyright (C) 2011 Texas Instruments, Inc. * Copyright (C) 2011 Texas Instruments, Inc.
* *
* Written by Ilan Elias <ilane@ti.com> * Written by Ilan Elias <ilane@ti.com>
...@@ -155,6 +156,24 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, ...@@ -155,6 +156,24 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
return data; 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, static int nci_add_new_protocol(struct nci_dev *ndev,
struct nfc_target *target, struct nfc_target *target,
__u8 rf_protocol, __u8 rf_protocol,
...@@ -164,6 +183,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, ...@@ -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_nfca_poll *nfca_poll;
struct rf_tech_specific_params_nfcb_poll *nfcb_poll; struct rf_tech_specific_params_nfcb_poll *nfcb_poll;
struct rf_tech_specific_params_nfcf_poll *nfcf_poll; struct rf_tech_specific_params_nfcf_poll *nfcf_poll;
struct rf_tech_specific_params_nfcv_poll *nfcv_poll;
__u32 protocol; __u32 protocol;
if (rf_protocol == NCI_RF_PROTOCOL_T1T) if (rf_protocol == NCI_RF_PROTOCOL_T1T)
...@@ -179,8 +199,10 @@ static int nci_add_new_protocol(struct nci_dev *ndev, ...@@ -179,8 +199,10 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
protocol = NFC_PROTO_FELICA_MASK; protocol = NFC_PROTO_FELICA_MASK;
else if (rf_protocol == NCI_RF_PROTOCOL_NFC_DEP) else if (rf_protocol == NCI_RF_PROTOCOL_NFC_DEP)
protocol = NFC_PROTO_NFC_DEP_MASK; protocol = NFC_PROTO_NFC_DEP_MASK;
else if (rf_protocol == NCI_RF_PROTOCOL_T5T)
protocol = NFC_PROTO_ISO15693_MASK;
else else
protocol = 0; protocol = nci_get_prop_rf_protocol(ndev, rf_protocol);
if (!(protocol & ndev->poll_prots)) { if (!(protocol & ndev->poll_prots)) {
pr_err("the target found does not have the desired protocol\n"); 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, ...@@ -213,6 +235,12 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
memcpy(target->sensf_res, nfcf_poll->sensf_res, memcpy(target->sensf_res, nfcf_poll->sensf_res,
target->sensf_res_len); 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 { } else {
pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode); pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode);
return -EPROTO; return -EPROTO;
...@@ -305,6 +333,11 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, ...@@ -305,6 +333,11 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
&(ntf.rf_tech_specific_params.nfcf_poll), data); &(ntf.rf_tech_specific_params.nfcf_poll), data);
break; 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: default:
pr_err("unsupported rf_tech_and_mode 0x%x\n", pr_err("unsupported rf_tech_and_mode 0x%x\n",
ntf.rf_tech_and_mode); ntf.rf_tech_and_mode);
...@@ -455,6 +488,11 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, ...@@ -455,6 +488,11 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
&(ntf.rf_tech_specific_params.nfcf_poll), data); &(ntf.rf_tech_specific_params.nfcf_poll), data);
break; 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: default:
pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
ntf.activation_rf_tech_and_mode); ntf.activation_rf_tech_and_mode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment