提交 330bd4ec 编写于 作者: J 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: NJohn W. Linville <linville@tuxdriver.com>
...@@ -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,
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30 #define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30
#define ST21NFCA_RF_READER_ISO15693_GATE 0x12 #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 * Reader gate for communication with contact-less cards using Type A
...@@ -45,21 +45,42 @@ ...@@ -45,21 +45,42 @@
#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
#define ST21NFCA_DM_GETINFO 0x13 #define ST21NFCA_DM_GETINFO 0x13
#define ST21NFCA_DM_GETINFO_PIPE_LIST 0x02 #define ST21NFCA_DM_GETINFO_PIPE_LIST 0x02
#define ST21NFCA_DM_GETINFO_PIPE_INFO 0x01 #define ST21NFCA_DM_GETINFO_PIPE_INFO 0x01
#define ST21NFCA_DM_PIPE_CREATED 0x02 #define ST21NFCA_DM_PIPE_CREATED 0x02
#define ST21NFCA_DM_PIPE_OPEN 0x04 #define ST21NFCA_DM_PIPE_OPEN 0x04
#define ST21NFCA_DM_RF_ACTIVE 0x80 #define ST21NFCA_DM_RF_ACTIVE 0x80
#define ST21NFCA_DM_DISCONNECT 0x30 #define ST21NFCA_DM_DISCONNECT 0x30
#define ST21NFCA_DM_IS_PIPE_OPEN(p) \ #define ST21NFCA_DM_IS_PIPE_OPEN(p) \
((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;
return 1;
} }
break; info->dep_info.curr_nfc_dep_pni = 0;
return 1;
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,9 +129,8 @@ static void st21nfca_tx_work(struct work_struct *work) ...@@ -128,9 +129,8 @@ 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;
...@@ -314,7 +316,7 @@ int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb) ...@@ -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; *skb_push(skb, 1) = skb->len;
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);
kfree_skb(skb); kfree_skb(skb);
return r; return r;
...@@ -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,8 +473,7 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb, ...@@ -484,8 +473,7 @@ 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,8 +603,7 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb, ...@@ -615,8 +603,7 @@ 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);
} }
int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb) int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *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;
} else if (r == -ENOMEM || r == -EBADMSG) {
return IRQ_HANDLED; 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");
nci_free_device(ndlc->ndev);
return r; }
err_regdev:
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: */
......
...@@ -36,7 +36,13 @@ ...@@ -36,7 +36,13 @@
* The trf7970a is very timing sensitive and the VIN, EN2, and EN * The trf7970a is very timing sensitive and the VIN, EN2, and EN
* pins must asserted in that order and with specific delays in between. * pins must asserted in that order and with specific delays in between.
* The delays used in the driver were provided by TI and have been * The delays used in the driver were provided by TI and have been
* confirmed to work with this driver. * confirmed to work with this driver. There is a bug with the current
* version of the trf7970a that requires that EN2 remain low no matter
* what. If it goes high, it will generate an RF field even when in
* passive target mode. TI has indicated that the chip will work okay
* when EN2 is left low. The 'en2-rf-quirk' device tree property
* indicates that trf7970a currently being used has the erratum and
* that EN2 must be kept low.
* *
* Timeouts are implemented using the delayed workqueue kernel facility. * Timeouts are implemented using the delayed workqueue kernel facility.
* Timeouts are required so things don't hang when there is no response * Timeouts are required so things don't hang when there is no response
...@@ -56,7 +62,7 @@ ...@@ -56,7 +62,7 @@
* way to abort a command that's already been sent to the tag is so turn * way to abort a command that's already been sent to the tag is so turn
* off power to the tag. If we do that, though, we'd have to go through * off power to the tag. If we do that, though, we'd have to go through
* the entire anticollision procedure again but the digital layer doesn't * the entire anticollision procedure again but the digital layer doesn't
* support that. So, if an abort is received before trf7970a_in_send_cmd() * support that. So, if an abort is received before trf7970a_send_cmd()
* has sent the command to the tag, it simply returns -ECANCELED. If the * has sent the command to the tag, it simply returns -ECANCELED. If the
* command has already been sent to the tag, then the driver continues * command has already been sent to the tag, then the driver continues
* normally and recieves the response data (or error) but just before * normally and recieves the response data (or error) but just before
...@@ -77,6 +83,13 @@ ...@@ -77,6 +83,13 @@
* been received and there isn't an error). The delay is 20 ms since delays * been received and there isn't an error). The delay is 20 ms since delays
* of ~16 ms have been observed during testing. * of ~16 ms have been observed during testing.
* *
* When transmitting a frame larger than the FIFO size (127 bytes), the
* driver will wait 20 ms for the FIFO to drain past the low-watermark
* and generate an interrupt. The low-watermark set to 32 bytes so the
* interrupt should fire after 127 - 32 = 95 bytes have been sent. At
* the lowest possible bit rate (6.62 kbps for 15693), it will take up
* to ~14.35 ms so 20 ms is used for the timeout.
*
* Type 2 write and sector select commands respond with a 4-bit ACK or NACK. * Type 2 write and sector select commands respond with a 4-bit ACK or NACK.
* Having only 4 bits in the FIFO won't normally generate an interrupt so * Having only 4 bits in the FIFO won't normally generate an interrupt so
* driver enables the '4_bit_RX' bit of the Special Functions register 1 * driver enables the '4_bit_RX' bit of the Special Functions register 1
...@@ -99,40 +112,43 @@ ...@@ -99,40 +112,43 @@
* Note under Table 1-1 in section 1.6 of * Note under Table 1-1 in section 1.6 of
* http://www.ti.com/lit/ug/scbu011/scbu011.pdf, that wait should be at least * http://www.ti.com/lit/ug/scbu011/scbu011.pdf, that wait should be at least
* 10 ms for TI Tag-it HF-I tags; however testing has shown that is not long * 10 ms for TI Tag-it HF-I tags; however testing has shown that is not long
* enough. For this reason, the driver waits 20 ms which seems to work * enough so 20 ms is used. So the timer is set to 40 ms - 20 ms to drain
* up to 127 bytes in the FIFO at the lowest bit rate plus another 20 ms to
* ensure the wait is long enough before sending the EOF. This seems to work
* reliably. * reliably.
*/ */
#define TRF7970A_SUPPORTED_PROTOCOLS \ #define TRF7970A_SUPPORTED_PROTOCOLS \
(NFC_PROTO_MIFARE_MASK | NFC_PROTO_ISO14443_MASK | \ (NFC_PROTO_MIFARE_MASK | NFC_PROTO_ISO14443_MASK | \
NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_FELICA_MASK | \ NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_FELICA_MASK | \
NFC_PROTO_ISO15693_MASK) NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)
#define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */ #define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */
/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends
* on what the current framing is, the address of the TX length byte 1
* register (0x1d), and the 2 byte length of the data to be transmitted.
* That totals 5 bytes.
*/
#define TRF7970A_TX_SKB_HEADROOM 5
#define TRF7970A_RX_SKB_ALLOC_SIZE 256 #define TRF7970A_RX_SKB_ALLOC_SIZE 256
#define TRF7970A_FIFO_SIZE 128 #define TRF7970A_FIFO_SIZE 127
/* TX length is 3 nibbles long ==> 4KB - 1 bytes max */ /* TX length is 3 nibbles long ==> 4KB - 1 bytes max */
#define TRF7970A_TX_MAX (4096 - 1) #define TRF7970A_TX_MAX (4096 - 1)
#define TRF7970A_WAIT_FOR_TX_IRQ 20
#define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT 20 #define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT 20
#define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT 3 #define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT 20
#define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF 20 #define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF 40
/* Guard times for various RF technologies (in us) */
#define TRF7970A_GUARD_TIME_NFCA 5000
#define TRF7970A_GUARD_TIME_NFCB 5000
#define TRF7970A_GUARD_TIME_NFCF 20000
#define TRF7970A_GUARD_TIME_15693 1000
/* Quirks */ /* Quirks */
/* Erratum: When reading IRQ Status register on trf7970a, we must issue a /* Erratum: When reading IRQ Status register on trf7970a, we must issue a
* read continuous command for IRQ Status and Collision Position registers. * read continuous command for IRQ Status and Collision Position registers.
*/ */
#define TRF7970A_QUIRK_IRQ_STATUS_READ_ERRATA BIT(0) #define TRF7970A_QUIRK_IRQ_STATUS_READ BIT(0)
#define TRF7970A_QUIRK_EN2_MUST_STAY_LOW BIT(1)
/* Direct commands */ /* Direct commands */
#define TRF7970A_CMD_IDLE 0x00 #define TRF7970A_CMD_IDLE 0x00
...@@ -149,8 +165,8 @@ ...@@ -149,8 +165,8 @@
#define TRF7970A_CMD_CLOSE_SLOT 0x15 #define TRF7970A_CMD_CLOSE_SLOT 0x15
#define TRF7970A_CMD_BLOCK_RX 0x16 #define TRF7970A_CMD_BLOCK_RX 0x16
#define TRF7970A_CMD_ENABLE_RX 0x17 #define TRF7970A_CMD_ENABLE_RX 0x17
#define TRF7970A_CMD_TEST_EXT_RF 0x18 #define TRF7970A_CMD_TEST_INT_RF 0x18
#define TRF7970A_CMD_TEST_INT_RF 0x19 #define TRF7970A_CMD_TEST_EXT_RF 0x19
#define TRF7970A_CMD_RX_GAIN_ADJUST 0x1a #define TRF7970A_CMD_RX_GAIN_ADJUST 0x1a
/* Bits determining whether its a direct command or register R/W, /* Bits determining whether its a direct command or register R/W,
...@@ -224,6 +240,15 @@ ...@@ -224,6 +240,15 @@
#define TRF7970A_ISO_CTRL_14443B_848 0x0f #define TRF7970A_ISO_CTRL_14443B_848 0x0f
#define TRF7970A_ISO_CTRL_FELICA_212 0x1a #define TRF7970A_ISO_CTRL_FELICA_212 0x1a
#define TRF7970A_ISO_CTRL_FELICA_424 0x1b #define TRF7970A_ISO_CTRL_FELICA_424 0x1b
#define TRF7970A_ISO_CTRL_NFC_NFCA_106 0x01
#define TRF7970A_ISO_CTRL_NFC_NFCF_212 0x02
#define TRF7970A_ISO_CTRL_NFC_NFCF_424 0x03
#define TRF7970A_ISO_CTRL_NFC_CE_14443A 0x00
#define TRF7970A_ISO_CTRL_NFC_CE_14443B 0x01
#define TRF7970A_ISO_CTRL_NFC_CE BIT(2)
#define TRF7970A_ISO_CTRL_NFC_ACTIVE BIT(3)
#define TRF7970A_ISO_CTRL_NFC_INITIATOR BIT(4)
#define TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE BIT(5)
#define TRF7970A_ISO_CTRL_RFID BIT(5) #define TRF7970A_ISO_CTRL_RFID BIT(5)
#define TRF7970A_ISO_CTRL_DIR_MODE BIT(6) #define TRF7970A_ISO_CTRL_DIR_MODE BIT(6)
#define TRF7970A_ISO_CTRL_RX_CRC_N BIT(7) /* true == No CRC */ #define TRF7970A_ISO_CTRL_RX_CRC_N BIT(7) /* true == No CRC */
...@@ -249,12 +274,32 @@ ...@@ -249,12 +274,32 @@
#define TRF7970A_MODULATOR_EN_OOK BIT(6) #define TRF7970A_MODULATOR_EN_OOK BIT(6)
#define TRF7970A_MODULATOR_27MHZ BIT(7) #define TRF7970A_MODULATOR_27MHZ BIT(7)
#define TRF7970A_RX_SPECIAL_SETTINGS_NO_LIM BIT(0)
#define TRF7970A_RX_SPECIAL_SETTINGS_AGCR BIT(1)
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_0DB (0x0 << 2)
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_5DB (0x1 << 2)
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_10DB (0x2 << 2)
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_15DB (0x3 << 2)
#define TRF7970A_RX_SPECIAL_SETTINGS_HBT BIT(4)
#define TRF7970A_RX_SPECIAL_SETTINGS_M848 BIT(5)
#define TRF7970A_RX_SPECIAL_SETTINGS_C424 BIT(6)
#define TRF7970A_RX_SPECIAL_SETTINGS_C212 BIT(7)
#define TRF7970A_REG_IO_CTRL_VRS(v) ((v) & 0x07)
#define TRF7970A_REG_IO_CTRL_IO_LOW BIT(5)
#define TRF7970A_REG_IO_CTRL_EN_EXT_PA BIT(6)
#define TRF7970A_REG_IO_CTRL_AUTO_REG BIT(7)
/* IRQ Status Register Bits */ /* IRQ Status Register Bits */
#define TRF7970A_IRQ_STATUS_NORESP BIT(0) /* ISO15693 only */ #define TRF7970A_IRQ_STATUS_NORESP BIT(0) /* ISO15693 only */
#define TRF7970A_IRQ_STATUS_NFC_COL_ERROR BIT(0)
#define TRF7970A_IRQ_STATUS_COL BIT(1) #define TRF7970A_IRQ_STATUS_COL BIT(1)
#define TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR BIT(2) #define TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR BIT(2)
#define TRF7970A_IRQ_STATUS_NFC_RF BIT(2)
#define TRF7970A_IRQ_STATUS_PARITY_ERROR BIT(3) #define TRF7970A_IRQ_STATUS_PARITY_ERROR BIT(3)
#define TRF7970A_IRQ_STATUS_NFC_SDD BIT(3)
#define TRF7970A_IRQ_STATUS_CRC_ERROR BIT(4) #define TRF7970A_IRQ_STATUS_CRC_ERROR BIT(4)
#define TRF7970A_IRQ_STATUS_NFC_PROTO_ERROR BIT(4)
#define TRF7970A_IRQ_STATUS_FIFO BIT(5) #define TRF7970A_IRQ_STATUS_FIFO BIT(5)
#define TRF7970A_IRQ_STATUS_SRX BIT(6) #define TRF7970A_IRQ_STATUS_SRX BIT(6)
#define TRF7970A_IRQ_STATUS_TX BIT(7) #define TRF7970A_IRQ_STATUS_TX BIT(7)
...@@ -265,6 +310,10 @@ ...@@ -265,6 +310,10 @@
TRF7970A_IRQ_STATUS_PARITY_ERROR | \ TRF7970A_IRQ_STATUS_PARITY_ERROR | \
TRF7970A_IRQ_STATUS_CRC_ERROR) TRF7970A_IRQ_STATUS_CRC_ERROR)
#define TRF7970A_RSSI_OSC_STATUS_RSSI_MASK (BIT(2) | BIT(1) | BIT(0))
#define TRF7970A_RSSI_OSC_STATUS_RSSI_X_MASK (BIT(5) | BIT(4) | BIT(3))
#define TRF7970A_RSSI_OSC_STATUS_RSSI_OSC_OK BIT(6)
#define TRF7970A_SPECIAL_FCN_REG1_COL_7_6 BIT(0) #define TRF7970A_SPECIAL_FCN_REG1_COL_7_6 BIT(0)
#define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL BIT(1) #define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL BIT(1)
#define TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX BIT(2) #define TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX BIT(2)
...@@ -281,6 +330,49 @@ ...@@ -281,6 +330,49 @@
#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_16 0x2 #define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_16 0x2
#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32 0x3 #define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32 0x3
#define TRF7970A_NFC_LOW_FIELD_LEVEL_RFDET(v) ((v) & 0x07)
#define TRF7970A_NFC_LOW_FIELD_LEVEL_CLEX_DIS BIT(7)
#define TRF7970A_NFC_TARGET_LEVEL_RFDET(v) ((v) & 0x07)
#define TRF7970A_NFC_TARGET_LEVEL_HI_RF BIT(3)
#define TRF7970A_NFC_TARGET_LEVEL_SDD_EN BIT(3)
#define TRF7970A_NFC_TARGET_LEVEL_LD_S_4BYTES (0x0 << 6)
#define TRF7970A_NFC_TARGET_LEVEL_LD_S_7BYTES (0x1 << 6)
#define TRF7970A_NFC_TARGET_LEVEL_LD_S_10BYTES (0x2 << 6)
#define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106 BIT(0)
#define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_212 BIT(1)
#define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_424 (BIT(0) | BIT(1))
#define TRF79070A_NFC_TARGET_PROTOCOL_PAS_14443B BIT(2)
#define TRF79070A_NFC_TARGET_PROTOCOL_PAS_106 BIT(3)
#define TRF79070A_NFC_TARGET_PROTOCOL_FELICA BIT(4)
#define TRF79070A_NFC_TARGET_PROTOCOL_RF_L BIT(6)
#define TRF79070A_NFC_TARGET_PROTOCOL_RF_H BIT(7)
#define TRF79070A_NFC_TARGET_PROTOCOL_106A \
(TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \
TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \
TRF79070A_NFC_TARGET_PROTOCOL_PAS_106 | \
TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106)
#define TRF79070A_NFC_TARGET_PROTOCOL_106B \
(TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \
TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \
TRF79070A_NFC_TARGET_PROTOCOL_PAS_14443B | \
TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106)
#define TRF79070A_NFC_TARGET_PROTOCOL_212F \
(TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \
TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \
TRF79070A_NFC_TARGET_PROTOCOL_FELICA | \
TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_212)
#define TRF79070A_NFC_TARGET_PROTOCOL_424F \
(TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \
TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \
TRF79070A_NFC_TARGET_PROTOCOL_FELICA | \
TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_424)
#define TRF7970A_FIFO_STATUS_OVERFLOW BIT(7) #define TRF7970A_FIFO_STATUS_OVERFLOW BIT(7)
/* NFC (ISO/IEC 14443A) Type 2 Tag commands */ /* NFC (ISO/IEC 14443A) Type 2 Tag commands */
...@@ -317,13 +409,16 @@ ...@@ -317,13 +409,16 @@
(ISO15693_REQ_FLAG_SUB_CARRIER | ISO15693_REQ_FLAG_DATA_RATE) (ISO15693_REQ_FLAG_SUB_CARRIER | ISO15693_REQ_FLAG_DATA_RATE)
enum trf7970a_state { enum trf7970a_state {
TRF7970A_ST_OFF, TRF7970A_ST_PWR_OFF,
TRF7970A_ST_RF_OFF,
TRF7970A_ST_IDLE, TRF7970A_ST_IDLE,
TRF7970A_ST_IDLE_RX_BLOCKED, TRF7970A_ST_IDLE_RX_BLOCKED,
TRF7970A_ST_WAIT_FOR_TX_FIFO, TRF7970A_ST_WAIT_FOR_TX_FIFO,
TRF7970A_ST_WAIT_FOR_RX_DATA, TRF7970A_ST_WAIT_FOR_RX_DATA,
TRF7970A_ST_WAIT_FOR_RX_DATA_CONT, TRF7970A_ST_WAIT_FOR_RX_DATA_CONT,
TRF7970A_ST_WAIT_TO_ISSUE_EOF, TRF7970A_ST_WAIT_TO_ISSUE_EOF,
TRF7970A_ST_LISTENING,
TRF7970A_ST_LISTENING_MD,
TRF7970A_ST_MAX TRF7970A_ST_MAX
}; };
...@@ -334,6 +429,7 @@ struct trf7970a { ...@@ -334,6 +429,7 @@ struct trf7970a {
struct regulator *regulator; struct regulator *regulator;
struct nfc_digital_dev *ddev; struct nfc_digital_dev *ddev;
u32 quirks; u32 quirks;
bool is_initiator;
bool aborting; bool aborting;
struct sk_buff *tx_skb; struct sk_buff *tx_skb;
struct sk_buff *rx_skb; struct sk_buff *rx_skb;
...@@ -344,8 +440,10 @@ struct trf7970a { ...@@ -344,8 +440,10 @@ struct trf7970a {
u8 iso_ctrl_tech; u8 iso_ctrl_tech;
u8 modulator_sys_clk_ctrl; u8 modulator_sys_clk_ctrl;
u8 special_fcn_reg1; u8 special_fcn_reg1;
unsigned int guard_time;
int technology; int technology;
int framing; int framing;
u8 md_rf_tech;
u8 tx_cmd; u8 tx_cmd;
bool issue_eof; bool issue_eof;
int en2_gpio; int en2_gpio;
...@@ -386,15 +484,28 @@ static int trf7970a_read(struct trf7970a *trf, u8 reg, u8 *val) ...@@ -386,15 +484,28 @@ static int trf7970a_read(struct trf7970a *trf, u8 reg, u8 *val)
return ret; return ret;
} }
static int trf7970a_read_cont(struct trf7970a *trf, u8 reg, static int trf7970a_read_cont(struct trf7970a *trf, u8 reg, u8 *buf, size_t len)
u8 *buf, size_t len)
{ {
u8 addr = reg | TRF7970A_CMD_BIT_RW | TRF7970A_CMD_BIT_CONTINUOUS; u8 addr = reg | TRF7970A_CMD_BIT_RW | TRF7970A_CMD_BIT_CONTINUOUS;
struct spi_transfer t[2];
struct spi_message m;
int ret; int ret;
dev_dbg(trf->dev, "read_cont(0x%x, %zd)\n", addr, len); dev_dbg(trf->dev, "read_cont(0x%x, %zd)\n", addr, len);
ret = spi_write_then_read(trf->spi, &addr, 1, buf, len); spi_message_init(&m);
memset(&t, 0, sizeof(t));
t[0].tx_buf = &addr;
t[0].len = sizeof(addr);
spi_message_add_tail(&t[0], &m);
t[1].rx_buf = buf;
t[1].len = len;
spi_message_add_tail(&t[1], &m);
ret = spi_sync(trf->spi, &m);
if (ret) if (ret)
dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr, dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr,
ret); ret);
...@@ -424,7 +535,7 @@ static int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status) ...@@ -424,7 +535,7 @@ static int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status)
addr = TRF7970A_IRQ_STATUS | TRF7970A_CMD_BIT_RW; addr = TRF7970A_IRQ_STATUS | TRF7970A_CMD_BIT_RW;
if (trf->quirks & TRF7970A_QUIRK_IRQ_STATUS_READ_ERRATA) { if (trf->quirks & TRF7970A_QUIRK_IRQ_STATUS_READ) {
addr |= TRF7970A_CMD_BIT_CONTINUOUS; addr |= TRF7970A_CMD_BIT_CONTINUOUS;
ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2); ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2);
} else { } else {
...@@ -440,10 +551,60 @@ static int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status) ...@@ -440,10 +551,60 @@ static int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status)
return ret; return ret;
} }
static void trf7970a_send_upstream(struct trf7970a *trf) static int trf7970a_read_target_proto(struct trf7970a *trf, u8 *target_proto)
{ {
u8 rssi; int ret;
u8 buf[2];
u8 addr;
addr = TRF79070A_NFC_TARGET_PROTOCOL | TRF7970A_CMD_BIT_RW |
TRF7970A_CMD_BIT_CONTINUOUS;
ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2);
if (ret)
dev_err(trf->dev, "%s - target_proto: Read failed: %d\n",
__func__, ret);
else
*target_proto = buf[0];
return ret;
}
static int trf7970a_mode_detect(struct trf7970a *trf, u8 *rf_tech)
{
int ret;
u8 target_proto, tech;
ret = trf7970a_read_target_proto(trf, &target_proto);
if (ret)
return ret;
switch (target_proto) {
case TRF79070A_NFC_TARGET_PROTOCOL_106A:
tech = NFC_DIGITAL_RF_TECH_106A;
break;
case TRF79070A_NFC_TARGET_PROTOCOL_106B:
tech = NFC_DIGITAL_RF_TECH_106B;
break;
case TRF79070A_NFC_TARGET_PROTOCOL_212F:
tech = NFC_DIGITAL_RF_TECH_212F;
break;
case TRF79070A_NFC_TARGET_PROTOCOL_424F:
tech = NFC_DIGITAL_RF_TECH_424F;
break;
default:
dev_dbg(trf->dev, "%s - mode_detect: target_proto: 0x%x\n",
__func__, target_proto);
return -EIO;
}
*rf_tech = tech;
return ret;
}
static void trf7970a_send_upstream(struct trf7970a *trf)
{
dev_kfree_skb_any(trf->tx_skb); dev_kfree_skb_any(trf->tx_skb);
trf->tx_skb = NULL; trf->tx_skb = NULL;
...@@ -452,13 +613,6 @@ static void trf7970a_send_upstream(struct trf7970a *trf) ...@@ -452,13 +613,6 @@ static void trf7970a_send_upstream(struct trf7970a *trf)
16, 1, trf->rx_skb->data, trf->rx_skb->len, 16, 1, trf->rx_skb->data, trf->rx_skb->len,
false); false);
/* According to the manual it is "good form" to reset the fifo and
* read the RSSI levels & oscillator status register here. It doesn't
* explain why.
*/
trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
trf7970a_read(trf, TRF7970A_RSSI_OSC_STATUS, &rssi);
trf->state = TRF7970A_ST_IDLE; trf->state = TRF7970A_ST_IDLE;
if (trf->aborting) { if (trf->aborting) {
...@@ -481,6 +635,8 @@ static void trf7970a_send_err_upstream(struct trf7970a *trf, int errno) ...@@ -481,6 +635,8 @@ static void trf7970a_send_err_upstream(struct trf7970a *trf, int errno)
{ {
dev_dbg(trf->dev, "Error - state: %d, errno: %d\n", trf->state, errno); dev_dbg(trf->dev, "Error - state: %d, errno: %d\n", trf->state, errno);
cancel_delayed_work(&trf->timeout_work);
kfree_skb(trf->rx_skb); kfree_skb(trf->rx_skb);
trf->rx_skb = ERR_PTR(errno); trf->rx_skb = ERR_PTR(errno);
...@@ -488,15 +644,29 @@ static void trf7970a_send_err_upstream(struct trf7970a *trf, int errno) ...@@ -488,15 +644,29 @@ static void trf7970a_send_err_upstream(struct trf7970a *trf, int errno)
} }
static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb, static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
unsigned int len) unsigned int len, u8 *prefix, unsigned int prefix_len)
{ {
struct spi_transfer t[2];
struct spi_message m;
unsigned int timeout; unsigned int timeout;
int ret; int ret;
print_hex_dump_debug("trf7970a tx data: ", DUMP_PREFIX_NONE, print_hex_dump_debug("trf7970a tx data: ", DUMP_PREFIX_NONE,
16, 1, skb->data, len, false); 16, 1, skb->data, len, false);
ret = spi_write(trf->spi, skb->data, len); spi_message_init(&m);
memset(&t, 0, sizeof(t));
t[0].tx_buf = prefix;
t[0].len = prefix_len;
spi_message_add_tail(&t[0], &m);
t[1].tx_buf = skb->data;
t[1].len = len;
spi_message_add_tail(&t[1], &m);
ret = spi_sync(trf->spi, &m);
if (ret) { if (ret) {
dev_err(trf->dev, "%s - Can't send tx data: %d\n", __func__, dev_err(trf->dev, "%s - Can't send tx data: %d\n", __func__,
ret); ret);
...@@ -514,7 +684,11 @@ static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb, ...@@ -514,7 +684,11 @@ static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF; timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF;
} else { } else {
trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA; trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
timeout = trf->timeout;
if (!trf->timeout)
timeout = TRF7970A_WAIT_FOR_TX_IRQ;
else
timeout = trf->timeout;
} }
} }
...@@ -532,6 +706,7 @@ static void trf7970a_fill_fifo(struct trf7970a *trf) ...@@ -532,6 +706,7 @@ static void trf7970a_fill_fifo(struct trf7970a *trf)
unsigned int len; unsigned int len;
int ret; int ret;
u8 fifo_bytes; u8 fifo_bytes;
u8 prefix;
ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes); ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
if (ret) { if (ret) {
...@@ -541,18 +716,21 @@ static void trf7970a_fill_fifo(struct trf7970a *trf) ...@@ -541,18 +716,21 @@ static void trf7970a_fill_fifo(struct trf7970a *trf)
dev_dbg(trf->dev, "Filling FIFO - fifo_bytes: 0x%x\n", fifo_bytes); dev_dbg(trf->dev, "Filling FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
if (fifo_bytes & TRF7970A_FIFO_STATUS_OVERFLOW) { fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
dev_err(trf->dev, "%s - fifo overflow: 0x%x\n", __func__,
fifo_bytes);
trf7970a_send_err_upstream(trf, -EIO);
return;
}
/* Calculate how much more data can be written to the fifo */ /* Calculate how much more data can be written to the fifo */
len = TRF7970A_FIFO_SIZE - fifo_bytes; len = TRF7970A_FIFO_SIZE - fifo_bytes;
if (!len) {
schedule_delayed_work(&trf->timeout_work,
msecs_to_jiffies(TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT));
return;
}
len = min(skb->len, len); len = min(skb->len, len);
ret = trf7970a_transmit(trf, skb, len); prefix = TRF7970A_CMD_BIT_CONTINUOUS | TRF7970A_FIFO_IO_REGISTER;
ret = trf7970a_transmit(trf, skb, len, &prefix, sizeof(prefix));
if (ret) if (ret)
trf7970a_send_err_upstream(trf, ret); trf7970a_send_err_upstream(trf, ret);
} }
...@@ -576,16 +754,11 @@ static void trf7970a_drain_fifo(struct trf7970a *trf, u8 status) ...@@ -576,16 +754,11 @@ static void trf7970a_drain_fifo(struct trf7970a *trf, u8 status)
dev_dbg(trf->dev, "Draining FIFO - fifo_bytes: 0x%x\n", fifo_bytes); dev_dbg(trf->dev, "Draining FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
if (!fifo_bytes) if (!fifo_bytes)
goto no_rx_data; goto no_rx_data;
if (fifo_bytes & TRF7970A_FIFO_STATUS_OVERFLOW) {
dev_err(trf->dev, "%s - fifo overflow: 0x%x\n", __func__,
fifo_bytes);
trf7970a_send_err_upstream(trf, -EIO);
return;
}
if (fifo_bytes > skb_tailroom(skb)) { if (fifo_bytes > skb_tailroom(skb)) {
skb = skb_copy_expand(skb, skb_headroom(skb), skb = skb_copy_expand(skb, skb_headroom(skb),
max_t(int, fifo_bytes, max_t(int, fifo_bytes,
...@@ -615,6 +788,21 @@ static void trf7970a_drain_fifo(struct trf7970a *trf, u8 status) ...@@ -615,6 +788,21 @@ static void trf7970a_drain_fifo(struct trf7970a *trf, u8 status)
status = TRF7970A_IRQ_STATUS_SRX; status = TRF7970A_IRQ_STATUS_SRX;
} else { } else {
trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA_CONT; trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA_CONT;
ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
if (ret) {
trf7970a_send_err_upstream(trf, ret);
return;
}
fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
/* If there are bytes in the FIFO, set status to '0' so
* the if stmt below doesn't fire and the driver will wait
* for the trf7970a to generate another RX interrupt.
*/
if (fifo_bytes)
status = 0;
} }
no_rx_data: no_rx_data:
...@@ -634,11 +822,11 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) ...@@ -634,11 +822,11 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
{ {
struct trf7970a *trf = dev_id; struct trf7970a *trf = dev_id;
int ret; int ret;
u8 status; u8 status, fifo_bytes, iso_ctrl;
mutex_lock(&trf->lock); mutex_lock(&trf->lock);
if (trf->state == TRF7970A_ST_OFF) { if (trf->state == TRF7970A_ST_RF_OFF) {
mutex_unlock(&trf->lock); mutex_unlock(&trf->lock);
return IRQ_NONE; return IRQ_NONE;
} }
...@@ -660,12 +848,12 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) ...@@ -660,12 +848,12 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
switch (trf->state) { switch (trf->state) {
case TRF7970A_ST_IDLE: case TRF7970A_ST_IDLE:
case TRF7970A_ST_IDLE_RX_BLOCKED: case TRF7970A_ST_IDLE_RX_BLOCKED:
/* If getting interrupts caused by RF noise, turn off the /* If initiator and getting interrupts caused by RF noise,
* receiver to avoid unnecessary interrupts. It will be * turn off the receiver to avoid unnecessary interrupts.
* turned back on in trf7970a_in_send_cmd() when the next * It will be turned back on in trf7970a_send_cmd() when
* command is issued. * the next command is issued.
*/ */
if (status & TRF7970A_IRQ_STATUS_ERROR) { if (trf->is_initiator && (status & TRF7970A_IRQ_STATUS_ERROR)) {
trf7970a_cmd(trf, TRF7970A_CMD_BLOCK_RX); trf7970a_cmd(trf, TRF7970A_CMD_BLOCK_RX);
trf->state = TRF7970A_ST_IDLE_RX_BLOCKED; trf->state = TRF7970A_ST_IDLE_RX_BLOCKED;
} }
...@@ -687,8 +875,68 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) ...@@ -687,8 +875,68 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
trf->ignore_timeout = trf->ignore_timeout =
!cancel_delayed_work(&trf->timeout_work); !cancel_delayed_work(&trf->timeout_work);
trf7970a_drain_fifo(trf, status); trf7970a_drain_fifo(trf, status);
} else if (status == TRF7970A_IRQ_STATUS_TX) { } else if (status & TRF7970A_IRQ_STATUS_FIFO) {
ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS,
&fifo_bytes);
fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
if (ret)
trf7970a_send_err_upstream(trf, ret);
else if (!fifo_bytes)
trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
} else if ((status == TRF7970A_IRQ_STATUS_TX) ||
(!trf->is_initiator &&
(status == (TRF7970A_IRQ_STATUS_TX |
TRF7970A_IRQ_STATUS_NFC_RF)))) {
trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET); trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
if (!trf->timeout) {
trf->ignore_timeout = !cancel_delayed_work(
&trf->timeout_work);
trf->rx_skb = ERR_PTR(0);
trf7970a_send_upstream(trf);
break;
}
if (trf->is_initiator)
break;
iso_ctrl = trf->iso_ctrl;
switch (trf->framing) {
case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
trf->iso_ctrl = 0xff; /* Force ISO_CTRL write */
break;
case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
trf->iso_ctrl = 0xff; /* Force ISO_CTRL write */
break;
case NFC_DIGITAL_FRAMING_NFCA_ANTICOL_COMPLETE:
ret = trf7970a_write(trf,
TRF7970A_SPECIAL_FCN_REG1,
TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL);
if (ret)
goto err_unlock_exit;
trf->special_fcn_reg1 =
TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL;
break;
default:
break;
}
if (iso_ctrl != trf->iso_ctrl) {
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL,
iso_ctrl);
if (ret)
goto err_unlock_exit;
trf->iso_ctrl = iso_ctrl;
}
} else { } else {
trf7970a_send_err_upstream(trf, -EIO); trf7970a_send_err_upstream(trf, -EIO);
} }
...@@ -697,11 +945,37 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) ...@@ -697,11 +945,37 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
if (status != TRF7970A_IRQ_STATUS_TX) if (status != TRF7970A_IRQ_STATUS_TX)
trf7970a_send_err_upstream(trf, -EIO); trf7970a_send_err_upstream(trf, -EIO);
break; break;
case TRF7970A_ST_LISTENING:
if (status & TRF7970A_IRQ_STATUS_SRX) {
trf->ignore_timeout =
!cancel_delayed_work(&trf->timeout_work);
trf7970a_drain_fifo(trf, status);
} else if (!(status & TRF7970A_IRQ_STATUS_NFC_RF)) {
trf7970a_send_err_upstream(trf, -EIO);
}
break;
case TRF7970A_ST_LISTENING_MD:
if (status & TRF7970A_IRQ_STATUS_SRX) {
trf->ignore_timeout =
!cancel_delayed_work(&trf->timeout_work);
ret = trf7970a_mode_detect(trf, &trf->md_rf_tech);
if (ret) {
trf7970a_send_err_upstream(trf, ret);
} else {
trf->state = TRF7970A_ST_LISTENING;
trf7970a_drain_fifo(trf, status);
}
} else if (!(status & TRF7970A_IRQ_STATUS_NFC_RF)) {
trf7970a_send_err_upstream(trf, -EIO);
}
break;
default: default:
dev_err(trf->dev, "%s - Driver in invalid state: %d\n", dev_err(trf->dev, "%s - Driver in invalid state: %d\n",
__func__, trf->state); __func__, trf->state);
} }
err_unlock_exit:
mutex_unlock(&trf->lock); mutex_unlock(&trf->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -742,7 +1016,7 @@ static void trf7970a_timeout_work_handler(struct work_struct *work) ...@@ -742,7 +1016,7 @@ static void trf7970a_timeout_work_handler(struct work_struct *work)
if (trf->ignore_timeout) if (trf->ignore_timeout)
trf->ignore_timeout = false; trf->ignore_timeout = false;
else if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT) else if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
trf7970a_send_upstream(trf); /* No more rx data so send up */ trf7970a_drain_fifo(trf, TRF7970A_IRQ_STATUS_SRX);
else if (trf->state == TRF7970A_ST_WAIT_TO_ISSUE_EOF) else if (trf->state == TRF7970A_ST_WAIT_TO_ISSUE_EOF)
trf7970a_issue_eof(trf); trf7970a_issue_eof(trf);
else else
...@@ -765,11 +1039,16 @@ static int trf7970a_init(struct trf7970a *trf) ...@@ -765,11 +1039,16 @@ static int trf7970a_init(struct trf7970a *trf)
if (ret) if (ret)
goto err_out; goto err_out;
/* Must clear NFC Target Detection Level reg due to erratum */ usleep_range(1000, 2000);
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0);
if (ret) if (ret)
goto err_out; goto err_out;
trf->modulator_sys_clk_ctrl = 0;
ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS, ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 | TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32); TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
...@@ -792,6 +1071,10 @@ static int trf7970a_init(struct trf7970a *trf) ...@@ -792,6 +1071,10 @@ static int trf7970a_init(struct trf7970a *trf)
static void trf7970a_switch_rf_off(struct trf7970a *trf) static void trf7970a_switch_rf_off(struct trf7970a *trf)
{ {
if ((trf->state == TRF7970A_ST_PWR_OFF) ||
(trf->state == TRF7970A_ST_RF_OFF))
return;
dev_dbg(trf->dev, "Switching rf off\n"); dev_dbg(trf->dev, "Switching rf off\n");
trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON; trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
...@@ -799,24 +1082,41 @@ static void trf7970a_switch_rf_off(struct trf7970a *trf) ...@@ -799,24 +1082,41 @@ static void trf7970a_switch_rf_off(struct trf7970a *trf)
trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, trf->chip_status_ctrl); trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, trf->chip_status_ctrl);
trf->aborting = false; trf->aborting = false;
trf->state = TRF7970A_ST_OFF; trf->state = TRF7970A_ST_RF_OFF;
pm_runtime_mark_last_busy(trf->dev); pm_runtime_mark_last_busy(trf->dev);
pm_runtime_put_autosuspend(trf->dev); pm_runtime_put_autosuspend(trf->dev);
} }
static void trf7970a_switch_rf_on(struct trf7970a *trf) static int trf7970a_switch_rf_on(struct trf7970a *trf)
{ {
int ret;
dev_dbg(trf->dev, "Switching rf on\n"); dev_dbg(trf->dev, "Switching rf on\n");
pm_runtime_get_sync(trf->dev); pm_runtime_get_sync(trf->dev);
if (trf->state != TRF7970A_ST_RF_OFF) { /* Power on, RF off */
dev_err(trf->dev, "%s - Incorrect state: %d\n", __func__,
trf->state);
return -EINVAL;
}
ret = trf7970a_init(trf);
if (ret) {
dev_err(trf->dev, "%s - Can't initialize: %d\n", __func__, ret);
return ret;
}
trf->state = TRF7970A_ST_IDLE; trf->state = TRF7970A_ST_IDLE;
return 0;
} }
static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on) static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
int ret = 0;
dev_dbg(trf->dev, "Switching RF - state: %d, on: %d\n", trf->state, on); dev_dbg(trf->dev, "Switching RF - state: %d, on: %d\n", trf->state, on);
...@@ -824,8 +1124,9 @@ static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on) ...@@ -824,8 +1124,9 @@ static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on)
if (on) { if (on) {
switch (trf->state) { switch (trf->state) {
case TRF7970A_ST_OFF: case TRF7970A_ST_PWR_OFF:
trf7970a_switch_rf_on(trf); case TRF7970A_ST_RF_OFF:
ret = trf7970a_switch_rf_on(trf);
break; break;
case TRF7970A_ST_IDLE: case TRF7970A_ST_IDLE:
case TRF7970A_ST_IDLE_RX_BLOCKED: case TRF7970A_ST_IDLE_RX_BLOCKED:
...@@ -834,26 +1135,31 @@ static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on) ...@@ -834,26 +1135,31 @@ static int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on)
dev_err(trf->dev, "%s - Invalid request: %d %d\n", dev_err(trf->dev, "%s - Invalid request: %d %d\n",
__func__, trf->state, on); __func__, trf->state, on);
trf7970a_switch_rf_off(trf); trf7970a_switch_rf_off(trf);
ret = -EINVAL;
} }
} else { } else {
switch (trf->state) { switch (trf->state) {
case TRF7970A_ST_OFF: case TRF7970A_ST_PWR_OFF:
case TRF7970A_ST_RF_OFF:
break; break;
default: default:
dev_err(trf->dev, "%s - Invalid request: %d %d\n", dev_err(trf->dev, "%s - Invalid request: %d %d\n",
__func__, trf->state, on); __func__, trf->state, on);
ret = -EINVAL;
/* FALLTHROUGH */ /* FALLTHROUGH */
case TRF7970A_ST_IDLE: case TRF7970A_ST_IDLE:
case TRF7970A_ST_IDLE_RX_BLOCKED: case TRF7970A_ST_IDLE_RX_BLOCKED:
case TRF7970A_ST_WAIT_FOR_RX_DATA:
case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
trf7970a_switch_rf_off(trf); trf7970a_switch_rf_off(trf);
} }
} }
mutex_unlock(&trf->lock); mutex_unlock(&trf->lock);
return 0; return ret;
} }
static int trf7970a_config_rf_tech(struct trf7970a *trf, int tech) static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
{ {
int ret = 0; int ret = 0;
...@@ -863,22 +1169,27 @@ static int trf7970a_config_rf_tech(struct trf7970a *trf, int tech) ...@@ -863,22 +1169,27 @@ static int trf7970a_config_rf_tech(struct trf7970a *trf, int tech)
case NFC_DIGITAL_RF_TECH_106A: case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106; trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK; trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
break; break;
case NFC_DIGITAL_RF_TECH_106B: case NFC_DIGITAL_RF_TECH_106B:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106; trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
break; break;
case NFC_DIGITAL_RF_TECH_212F: case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212; trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break; break;
case NFC_DIGITAL_RF_TECH_424F: case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424; trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10; trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break; break;
case NFC_DIGITAL_RF_TECH_ISO15693: case NFC_DIGITAL_RF_TECH_ISO15693:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648; trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK; trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_15693;
break; break;
default: default:
dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech); dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
...@@ -887,12 +1198,54 @@ static int trf7970a_config_rf_tech(struct trf7970a *trf, int tech) ...@@ -887,12 +1198,54 @@ static int trf7970a_config_rf_tech(struct trf7970a *trf, int tech)
trf->technology = tech; trf->technology = tech;
/* If in initiator mode and not changing the RF tech due to a
* PSL sequence (indicated by 'trf->iso_ctrl == 0xff' from
* trf7970a_init()), clear the NFC Target Detection Level register
* due to erratum.
*/
if (trf->iso_ctrl == 0xff)
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
return ret; return ret;
} }
static int trf7970a_config_framing(struct trf7970a *trf, int framing) static int trf7970a_is_rf_field(struct trf7970a *trf, bool *is_rf_field)
{
int ret;
u8 rssi;
ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
trf->chip_status_ctrl | TRF7970A_CHIP_STATUS_REC_ON);
if (ret)
return ret;
ret = trf7970a_cmd(trf, TRF7970A_CMD_TEST_EXT_RF);
if (ret)
return ret;
usleep_range(50, 60);
ret = trf7970a_read(trf, TRF7970A_RSSI_OSC_STATUS, &rssi);
if (ret)
return ret;
ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
trf->chip_status_ctrl);
if (ret)
return ret;
if (rssi & TRF7970A_RSSI_OSC_STATUS_RSSI_MASK)
*is_rf_field = true;
else
*is_rf_field = false;
return 0;
}
static int trf7970a_in_config_framing(struct trf7970a *trf, int framing)
{ {
u8 iso_ctrl = trf->iso_ctrl_tech; u8 iso_ctrl = trf->iso_ctrl_tech;
bool is_rf_field = false;
int ret; int ret;
dev_dbg(trf->dev, "framing: %d\n", framing); dev_dbg(trf->dev, "framing: %d\n", framing);
...@@ -911,6 +1264,8 @@ static int trf7970a_config_framing(struct trf7970a *trf, int framing) ...@@ -911,6 +1264,8 @@ static int trf7970a_config_framing(struct trf7970a *trf, int framing)
case NFC_DIGITAL_FRAMING_NFCF_T3T: case NFC_DIGITAL_FRAMING_NFCF_T3T:
case NFC_DIGITAL_FRAMING_ISO15693_INVENTORY: case NFC_DIGITAL_FRAMING_ISO15693_INVENTORY:
case NFC_DIGITAL_FRAMING_ISO15693_T5T: case NFC_DIGITAL_FRAMING_ISO15693_T5T:
case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP:
case NFC_DIGITAL_FRAMING_NFCF_NFC_DEP:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT; trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N; iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
break; break;
...@@ -925,6 +1280,15 @@ static int trf7970a_config_framing(struct trf7970a *trf, int framing) ...@@ -925,6 +1280,15 @@ static int trf7970a_config_framing(struct trf7970a *trf, int framing)
trf->framing = framing; trf->framing = framing;
if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
ret = trf7970a_is_rf_field(trf, &is_rf_field);
if (ret)
return ret;
if (is_rf_field)
return -EBUSY;
}
if (iso_ctrl != trf->iso_ctrl) { if (iso_ctrl != trf->iso_ctrl) {
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl); ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
if (ret) if (ret)
...@@ -947,7 +1311,7 @@ static int trf7970a_config_framing(struct trf7970a *trf, int framing) ...@@ -947,7 +1311,7 @@ static int trf7970a_config_framing(struct trf7970a *trf, int framing)
trf->chip_status_ctrl |= TRF7970A_CHIP_STATUS_RF_ON; trf->chip_status_ctrl |= TRF7970A_CHIP_STATUS_RF_ON;
usleep_range(5000, 6000); usleep_range(trf->guard_time, trf->guard_time + 1000);
} }
return 0; return 0;
...@@ -963,21 +1327,28 @@ static int trf7970a_in_configure_hw(struct nfc_digital_dev *ddev, int type, ...@@ -963,21 +1327,28 @@ static int trf7970a_in_configure_hw(struct nfc_digital_dev *ddev, int type,
mutex_lock(&trf->lock); mutex_lock(&trf->lock);
if (trf->state == TRF7970A_ST_OFF) trf->is_initiator = true;
trf7970a_switch_rf_on(trf);
if ((trf->state == TRF7970A_ST_PWR_OFF) ||
(trf->state == TRF7970A_ST_RF_OFF)) {
ret = trf7970a_switch_rf_on(trf);
if (ret)
goto err_unlock;
}
switch (type) { switch (type) {
case NFC_DIGITAL_CONFIG_RF_TECH: case NFC_DIGITAL_CONFIG_RF_TECH:
ret = trf7970a_config_rf_tech(trf, param); ret = trf7970a_in_config_rf_tech(trf, param);
break; break;
case NFC_DIGITAL_CONFIG_FRAMING: case NFC_DIGITAL_CONFIG_FRAMING:
ret = trf7970a_config_framing(trf, param); ret = trf7970a_in_config_framing(trf, param);
break; break;
default: default:
dev_dbg(trf->dev, "Unknown type: %d\n", type); dev_dbg(trf->dev, "Unknown type: %d\n", type);
ret = -EINVAL; ret = -EINVAL;
} }
err_unlock:
mutex_unlock(&trf->lock); mutex_unlock(&trf->lock);
return ret; return ret;
} }
...@@ -1067,14 +1438,15 @@ static int trf7970a_per_cmd_config(struct trf7970a *trf, struct sk_buff *skb) ...@@ -1067,14 +1438,15 @@ static int trf7970a_per_cmd_config(struct trf7970a *trf, struct sk_buff *skb)
return 0; return 0;
} }
static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev, static int trf7970a_send_cmd(struct nfc_digital_dev *ddev,
struct sk_buff *skb, u16 timeout, struct sk_buff *skb, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg) nfc_digital_cmd_complete_t cb, void *arg)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
char *prefix; u8 prefix[5];
unsigned int len; unsigned int len;
int ret; int ret;
u8 status;
dev_dbg(trf->dev, "New request - state: %d, timeout: %d ms, len: %d\n", dev_dbg(trf->dev, "New request - state: %d, timeout: %d ms, len: %d\n",
trf->state, timeout, skb->len); trf->state, timeout, skb->len);
...@@ -1099,12 +1471,14 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev, ...@@ -1099,12 +1471,14 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
goto out_err; goto out_err;
} }
trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE, if (timeout) {
GFP_KERNEL); trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
if (!trf->rx_skb) { GFP_KERNEL);
dev_dbg(trf->dev, "Can't alloc rx_skb\n"); if (!trf->rx_skb) {
ret = -ENOMEM; dev_dbg(trf->dev, "Can't alloc rx_skb\n");
goto out_err; ret = -ENOMEM;
goto out_err;
}
} }
if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) { if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) {
...@@ -1115,9 +1489,11 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev, ...@@ -1115,9 +1489,11 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
trf->state = TRF7970A_ST_IDLE; trf->state = TRF7970A_ST_IDLE;
} }
ret = trf7970a_per_cmd_config(trf, skb); if (trf->is_initiator) {
if (ret) ret = trf7970a_per_cmd_config(trf, skb);
goto out_err; if (ret)
goto out_err;
}
trf->ddev = ddev; trf->ddev = ddev;
trf->tx_skb = skb; trf->tx_skb = skb;
...@@ -1127,11 +1503,11 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev, ...@@ -1127,11 +1503,11 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
trf->ignore_timeout = false; trf->ignore_timeout = false;
len = skb->len; len = skb->len;
prefix = skb_push(skb, TRF7970A_TX_SKB_HEADROOM);
/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends /* TX data must be prefixed with a FIFO reset cmd, a cmd that depends
* on what the current framing is, the address of the TX length byte 1 * on what the current framing is, the address of the TX length byte 1
* register (0x1d), and the 2 byte length of the data to be transmitted. * register (0x1d), and the 2 byte length of the data to be transmitted.
* That totals 5 bytes.
*/ */
prefix[0] = TRF7970A_CMD_BIT_CTRL | prefix[0] = TRF7970A_CMD_BIT_CTRL |
TRF7970A_CMD_BIT_OPCODE(TRF7970A_CMD_FIFO_RESET); TRF7970A_CMD_BIT_OPCODE(TRF7970A_CMD_FIFO_RESET);
...@@ -1150,9 +1526,12 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev, ...@@ -1150,9 +1526,12 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
len = min_t(int, skb->len, TRF7970A_FIFO_SIZE); len = min_t(int, skb->len, TRF7970A_FIFO_SIZE);
usleep_range(1000, 2000); /* Clear possible spurious interrupt */
ret = trf7970a_read_irqstatus(trf, &status);
if (ret)
goto out_err;
ret = trf7970a_transmit(trf, skb, len); ret = trf7970a_transmit(trf, skb, len, prefix, sizeof(prefix));
if (ret) { if (ret) {
kfree_skb(trf->rx_skb); kfree_skb(trf->rx_skb);
trf->rx_skb = NULL; trf->rx_skb = NULL;
...@@ -1163,46 +1542,272 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev, ...@@ -1163,46 +1542,272 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
return ret; return ret;
} }
static int trf7970a_tg_configure_hw(struct nfc_digital_dev *ddev, static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
int type, int param) {
int ret = 0;
dev_dbg(trf->dev, "rf technology: %d\n", tech);
switch (tech) {
case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_CE |
TRF7970A_ISO_CTRL_NFC_CE_14443A;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_212;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_424;
trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
break;
default:
dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
return -EINVAL;
}
trf->technology = tech;
/* Normally we write the ISO_CTRL register in
* trf7970a_tg_config_framing() because the framing can change
* the value written. However, when sending a PSL RES,
* digital_tg_send_psl_res_complete() doesn't call
* trf7970a_tg_config_framing() so we must write the register
* here.
*/
if ((trf->framing == NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED) &&
(trf->iso_ctrl_tech != trf->iso_ctrl)) {
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL,
trf->iso_ctrl_tech);
trf->iso_ctrl = trf->iso_ctrl_tech;
}
return ret;
}
/* Since this is a target routine, several of the framing calls are
* made between receiving the request and sending the response so they
* should take effect until after the response is sent. This is accomplished
* by skipping the ISO_CTRL register write here and doing it in the interrupt
* handler.
*/
static int trf7970a_tg_config_framing(struct trf7970a *trf, int framing)
{
u8 iso_ctrl = trf->iso_ctrl_tech;
int ret;
dev_dbg(trf->dev, "framing: %d\n", framing);
switch (framing) {
case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
break;
case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A:
case NFC_DIGITAL_FRAMING_NFCA_ANTICOL_COMPLETE:
/* These ones are applied in the interrupt handler */
iso_ctrl = trf->iso_ctrl; /* Don't write to ISO_CTRL yet */
break;
case NFC_DIGITAL_FRAMING_NFCF_NFC_DEP:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
break;
case NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
break;
default:
dev_dbg(trf->dev, "Unsupported Framing: %d\n", framing);
return -EINVAL;
}
trf->framing = framing;
if (iso_ctrl != trf->iso_ctrl) {
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
if (ret)
return ret;
trf->iso_ctrl = iso_ctrl;
ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
trf->modulator_sys_clk_ctrl);
if (ret)
return ret;
}
if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
trf->chip_status_ctrl |
TRF7970A_CHIP_STATUS_RF_ON);
if (ret)
return ret;
trf->chip_status_ctrl |= TRF7970A_CHIP_STATUS_RF_ON;
}
return 0;
}
static int trf7970a_tg_configure_hw(struct nfc_digital_dev *ddev, int type,
int param)
{
struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
int ret;
dev_dbg(trf->dev, "Configure hw - type: %d, param: %d\n", type, param);
mutex_lock(&trf->lock);
trf->is_initiator = false;
if ((trf->state == TRF7970A_ST_PWR_OFF) ||
(trf->state == TRF7970A_ST_RF_OFF)) {
ret = trf7970a_switch_rf_on(trf);
if (ret)
goto err_unlock;
}
switch (type) {
case NFC_DIGITAL_CONFIG_RF_TECH:
ret = trf7970a_tg_config_rf_tech(trf, param);
break;
case NFC_DIGITAL_CONFIG_FRAMING:
ret = trf7970a_tg_config_framing(trf, param);
break;
default:
dev_dbg(trf->dev, "Unknown type: %d\n", type);
ret = -EINVAL;
}
err_unlock:
mutex_unlock(&trf->lock);
return ret;
}
static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg, bool mode_detect)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
int ret;
mutex_lock(&trf->lock);
dev_dbg(trf->dev, "Unsupported interface\n"); if ((trf->state != TRF7970A_ST_IDLE) &&
(trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
trf->state);
ret = -EIO;
goto out_err;
}
return -EINVAL; if (trf->aborting) {
dev_dbg(trf->dev, "Abort process complete\n");
trf->aborting = false;
ret = -ECANCELED;
goto out_err;
}
trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
GFP_KERNEL);
if (!trf->rx_skb) {
dev_dbg(trf->dev, "Can't alloc rx_skb\n");
ret = -ENOMEM;
goto out_err;
}
ret = trf7970a_write(trf, TRF7970A_RX_SPECIAL_SETTINGS,
TRF7970A_RX_SPECIAL_SETTINGS_HBT |
TRF7970A_RX_SPECIAL_SETTINGS_M848 |
TRF7970A_RX_SPECIAL_SETTINGS_C424 |
TRF7970A_RX_SPECIAL_SETTINGS_C212);
if (ret)
goto out_err;
ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
TRF7970A_REG_IO_CTRL_VRS(0x1));
if (ret)
goto out_err;
ret = trf7970a_write(trf, TRF7970A_NFC_LOW_FIELD_LEVEL,
TRF7970A_NFC_LOW_FIELD_LEVEL_RFDET(0x3));
if (ret)
goto out_err;
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL,
TRF7970A_NFC_TARGET_LEVEL_RFDET(0x7));
if (ret)
goto out_err;
trf->ddev = ddev;
trf->cb = cb;
trf->cb_arg = arg;
trf->timeout = timeout;
trf->ignore_timeout = false;
ret = trf7970a_cmd(trf, TRF7970A_CMD_ENABLE_RX);
if (ret)
goto out_err;
trf->state = mode_detect ? TRF7970A_ST_LISTENING_MD :
TRF7970A_ST_LISTENING;
schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout));
out_err:
mutex_unlock(&trf->lock);
return ret;
} }
static int trf7970a_tg_send_cmd(struct nfc_digital_dev *ddev, static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
struct sk_buff *skb, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg) nfc_digital_cmd_complete_t cb, void *arg)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
dev_dbg(trf->dev, "Unsupported interface\n"); dev_dbg(trf->dev, "Listen - state: %d, timeout: %d ms\n",
trf->state, timeout);
return -EINVAL; return _trf7970a_tg_listen(ddev, timeout, cb, arg, false);
} }
static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, static int trf7970a_tg_listen_md(struct nfc_digital_dev *ddev,
u16 timeout, nfc_digital_cmd_complete_t cb, void *arg) u16 timeout, nfc_digital_cmd_complete_t cb, void *arg)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
int ret;
dev_dbg(trf->dev, "Listen MD - state: %d, timeout: %d ms\n",
trf->state, timeout);
dev_dbg(trf->dev, "Unsupported interface\n"); ret = trf7970a_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
NFC_DIGITAL_RF_TECH_106A);
if (ret)
return ret;
return -EINVAL; ret = trf7970a_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
NFC_DIGITAL_FRAMING_NFCA_NFC_DEP);
if (ret)
return ret;
return _trf7970a_tg_listen(ddev, timeout, cb, arg, true);
} }
static int trf7970a_tg_listen_mdaa(struct nfc_digital_dev *ddev, static int trf7970a_tg_get_rf_tech(struct nfc_digital_dev *ddev, u8 *rf_tech)
struct digital_tg_mdaa_params *mdaa_params,
u16 timeout, nfc_digital_cmd_complete_t cb, void *arg)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
dev_dbg(trf->dev, "Unsupported interface\n"); dev_dbg(trf->dev, "Get RF Tech - state: %d, rf_tech: %d\n",
trf->state, trf->md_rf_tech);
return -EINVAL; *rf_tech = trf->md_rf_tech;
return 0;
} }
static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev) static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev)
...@@ -1220,6 +1825,11 @@ static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev) ...@@ -1220,6 +1825,11 @@ static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev)
case TRF7970A_ST_WAIT_TO_ISSUE_EOF: case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
trf->aborting = true; trf->aborting = true;
break; break;
case TRF7970A_ST_LISTENING:
trf->ignore_timeout = !cancel_delayed_work(&trf->timeout_work);
trf7970a_send_err_upstream(trf, -ECANCELED);
dev_dbg(trf->dev, "Abort process complete\n");
break;
default: default:
break; break;
} }
...@@ -1229,15 +1839,114 @@ static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev) ...@@ -1229,15 +1839,114 @@ static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev)
static struct nfc_digital_ops trf7970a_nfc_ops = { static struct nfc_digital_ops trf7970a_nfc_ops = {
.in_configure_hw = trf7970a_in_configure_hw, .in_configure_hw = trf7970a_in_configure_hw,
.in_send_cmd = trf7970a_in_send_cmd, .in_send_cmd = trf7970a_send_cmd,
.tg_configure_hw = trf7970a_tg_configure_hw, .tg_configure_hw = trf7970a_tg_configure_hw,
.tg_send_cmd = trf7970a_tg_send_cmd, .tg_send_cmd = trf7970a_send_cmd,
.tg_listen = trf7970a_tg_listen, .tg_listen = trf7970a_tg_listen,
.tg_listen_mdaa = trf7970a_tg_listen_mdaa, .tg_listen_md = trf7970a_tg_listen_md,
.tg_get_rf_tech = trf7970a_tg_get_rf_tech,
.switch_rf = trf7970a_switch_rf, .switch_rf = trf7970a_switch_rf,
.abort_cmd = trf7970a_abort_cmd, .abort_cmd = trf7970a_abort_cmd,
}; };
static int trf7970a_power_up(struct trf7970a *trf)
{
int ret;
dev_dbg(trf->dev, "Powering up - state: %d\n", trf->state);
if (trf->state != TRF7970A_ST_PWR_OFF)
return 0;
ret = regulator_enable(trf->regulator);
if (ret) {
dev_err(trf->dev, "%s - Can't enable VIN: %d\n", __func__, ret);
return ret;
}
usleep_range(5000, 6000);
if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) {
gpio_set_value(trf->en2_gpio, 1);
usleep_range(1000, 2000);
}
gpio_set_value(trf->en_gpio, 1);
usleep_range(20000, 21000);
trf->state = TRF7970A_ST_RF_OFF;
return 0;
}
static int trf7970a_power_down(struct trf7970a *trf)
{
int ret;
dev_dbg(trf->dev, "Powering down - state: %d\n", trf->state);
if (trf->state == TRF7970A_ST_PWR_OFF)
return 0;
if (trf->state != TRF7970A_ST_RF_OFF) {
dev_dbg(trf->dev, "Can't power down - not RF_OFF state (%d)\n",
trf->state);
return -EBUSY;
}
gpio_set_value(trf->en_gpio, 0);
gpio_set_value(trf->en2_gpio, 0);
ret = regulator_disable(trf->regulator);
if (ret)
dev_err(trf->dev, "%s - Can't disable VIN: %d\n", __func__,
ret);
trf->state = TRF7970A_ST_PWR_OFF;
return ret;
}
static int trf7970a_startup(struct trf7970a *trf)
{
int ret;
ret = trf7970a_power_up(trf);
if (ret)
return ret;
pm_runtime_set_active(trf->dev);
pm_runtime_enable(trf->dev);
pm_runtime_mark_last_busy(trf->dev);
return 0;
}
static void trf7970a_shutdown(struct trf7970a *trf)
{
switch (trf->state) {
case TRF7970A_ST_WAIT_FOR_TX_FIFO:
case TRF7970A_ST_WAIT_FOR_RX_DATA:
case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
case TRF7970A_ST_LISTENING:
trf7970a_send_err_upstream(trf, -ECANCELED);
/* FALLTHROUGH */
case TRF7970A_ST_IDLE:
case TRF7970A_ST_IDLE_RX_BLOCKED:
trf7970a_switch_rf_off(trf);
break;
default:
break;
}
pm_runtime_disable(trf->dev);
pm_runtime_set_suspended(trf->dev);
trf7970a_power_down(trf);
}
static int trf7970a_get_autosuspend_delay(struct device_node *np) static int trf7970a_get_autosuspend_delay(struct device_node *np)
{ {
int autosuspend_delay, ret; int autosuspend_delay, ret;
...@@ -1246,15 +1955,18 @@ static int trf7970a_get_autosuspend_delay(struct device_node *np) ...@@ -1246,15 +1955,18 @@ static int trf7970a_get_autosuspend_delay(struct device_node *np)
if (ret) if (ret)
autosuspend_delay = TRF7970A_AUTOSUSPEND_DELAY; autosuspend_delay = TRF7970A_AUTOSUSPEND_DELAY;
of_node_put(np);
return autosuspend_delay; return autosuspend_delay;
} }
static int trf7970a_get_vin_voltage_override(struct device_node *np,
u32 *vin_uvolts)
{
return of_property_read_u32(np, "vin-voltage-override", vin_uvolts);
}
static int trf7970a_probe(struct spi_device *spi) static int trf7970a_probe(struct spi_device *spi)
{ {
struct device_node *np = spi->dev.of_node; struct device_node *np = spi->dev.of_node;
const struct spi_device_id *id = spi_get_device_id(spi);
struct trf7970a *trf; struct trf7970a *trf;
int uvolts, autosuspend_delay, ret; int uvolts, autosuspend_delay, ret;
...@@ -1267,14 +1979,22 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -1267,14 +1979,22 @@ static int trf7970a_probe(struct spi_device *spi)
if (!trf) if (!trf)
return -ENOMEM; return -ENOMEM;
trf->state = TRF7970A_ST_OFF; trf->state = TRF7970A_ST_PWR_OFF;
trf->dev = &spi->dev; trf->dev = &spi->dev;
trf->spi = spi; trf->spi = spi;
trf->quirks = id->driver_data;
spi->mode = SPI_MODE_1; spi->mode = SPI_MODE_1;
spi->bits_per_word = 8; spi->bits_per_word = 8;
ret = spi_setup(spi);
if (ret < 0) {
dev_err(trf->dev, "Can't set up SPI Communication\n");
return ret;
}
if (of_property_read_bool(np, "irq-status-read-quirk"))
trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ;
/* There are two enable pins - both must be present */ /* There are two enable pins - both must be present */
trf->en_gpio = of_get_named_gpio(np, "ti,enable-gpios", 0); trf->en_gpio = of_get_named_gpio(np, "ti,enable-gpios", 0);
if (!gpio_is_valid(trf->en_gpio)) { if (!gpio_is_valid(trf->en_gpio)) {
...@@ -1283,7 +2003,7 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -1283,7 +2003,7 @@ static int trf7970a_probe(struct spi_device *spi)
} }
ret = devm_gpio_request_one(trf->dev, trf->en_gpio, ret = devm_gpio_request_one(trf->dev, trf->en_gpio,
GPIOF_DIR_OUT | GPIOF_INIT_LOW, "EN"); GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN");
if (ret) { if (ret) {
dev_err(trf->dev, "Can't request EN GPIO: %d\n", ret); dev_err(trf->dev, "Can't request EN GPIO: %d\n", ret);
return ret; return ret;
...@@ -1296,12 +2016,15 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -1296,12 +2016,15 @@ static int trf7970a_probe(struct spi_device *spi)
} }
ret = devm_gpio_request_one(trf->dev, trf->en2_gpio, ret = devm_gpio_request_one(trf->dev, trf->en2_gpio,
GPIOF_DIR_OUT | GPIOF_INIT_LOW, "EN2"); GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2");
if (ret) { if (ret) {
dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret); dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret);
return ret; return ret;
} }
if (of_property_read_bool(np, "en2-rf-quirk"))
trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL, ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL,
trf7970a_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, trf7970a_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"trf7970a", trf); "trf7970a", trf);
...@@ -1326,15 +2049,17 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -1326,15 +2049,17 @@ static int trf7970a_probe(struct spi_device *spi)
goto err_destroy_lock; goto err_destroy_lock;
} }
uvolts = regulator_get_voltage(trf->regulator); ret = trf7970a_get_vin_voltage_override(np, &uvolts);
if (ret)
uvolts = regulator_get_voltage(trf->regulator);
if (uvolts > 4000000) if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3; trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops, trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS, TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC, TRF7970A_TX_SKB_HEADROOM, NFC_DIGITAL_DRV_CAPS_IN_CRC |
0); NFC_DIGITAL_DRV_CAPS_TG_CRC, 0, 0);
if (!trf->ddev) { if (!trf->ddev) {
dev_err(trf->dev, "Can't allocate NFC digital device\n"); dev_err(trf->dev, "Can't allocate NFC digital device\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1349,19 +2074,23 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -1349,19 +2074,23 @@ static int trf7970a_probe(struct spi_device *spi)
pm_runtime_set_autosuspend_delay(trf->dev, autosuspend_delay); pm_runtime_set_autosuspend_delay(trf->dev, autosuspend_delay);
pm_runtime_use_autosuspend(trf->dev); pm_runtime_use_autosuspend(trf->dev);
pm_runtime_enable(trf->dev);
ret = trf7970a_startup(trf);
if (ret)
goto err_free_ddev;
ret = nfc_digital_register_device(trf->ddev); ret = nfc_digital_register_device(trf->ddev);
if (ret) { if (ret) {
dev_err(trf->dev, "Can't register NFC digital device: %d\n", dev_err(trf->dev, "Can't register NFC digital device: %d\n",
ret); ret);
goto err_free_ddev; goto err_shutdown;
} }
return 0; return 0;
err_shutdown:
trf7970a_shutdown(trf);
err_free_ddev: err_free_ddev:
pm_runtime_disable(trf->dev);
nfc_digital_free_device(trf->ddev); nfc_digital_free_device(trf->ddev);
err_disable_regulator: err_disable_regulator:
regulator_disable(trf->regulator); regulator_disable(trf->regulator);
...@@ -1376,25 +2105,10 @@ static int trf7970a_remove(struct spi_device *spi) ...@@ -1376,25 +2105,10 @@ static int trf7970a_remove(struct spi_device *spi)
mutex_lock(&trf->lock); mutex_lock(&trf->lock);
switch (trf->state) { trf7970a_shutdown(trf);
case TRF7970A_ST_WAIT_FOR_TX_FIFO:
case TRF7970A_ST_WAIT_FOR_RX_DATA:
case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
trf7970a_send_err_upstream(trf, -ECANCELED);
/* FALLTHROUGH */
case TRF7970A_ST_IDLE:
case TRF7970A_ST_IDLE_RX_BLOCKED:
pm_runtime_put_sync(trf->dev);
break;
default:
break;
}
mutex_unlock(&trf->lock); mutex_unlock(&trf->lock);
pm_runtime_disable(trf->dev);
nfc_digital_unregister_device(trf->ddev); nfc_digital_unregister_device(trf->ddev);
nfc_digital_free_device(trf->ddev); nfc_digital_free_device(trf->ddev);
...@@ -1405,72 +2119,83 @@ static int trf7970a_remove(struct spi_device *spi) ...@@ -1405,72 +2119,83 @@ static int trf7970a_remove(struct spi_device *spi)
return 0; return 0;
} }
#ifdef CONFIG_PM_RUNTIME #ifdef CONFIG_PM_SLEEP
static int trf7970a_pm_runtime_suspend(struct device *dev) static int trf7970a_suspend(struct device *dev)
{
struct spi_device *spi = container_of(dev, struct spi_device, dev);
struct trf7970a *trf = spi_get_drvdata(spi);
dev_dbg(dev, "Suspend\n");
mutex_lock(&trf->lock);
trf7970a_shutdown(trf);
mutex_unlock(&trf->lock);
return 0;
}
static int trf7970a_resume(struct device *dev)
{ {
struct spi_device *spi = container_of(dev, struct spi_device, dev); struct spi_device *spi = container_of(dev, struct spi_device, dev);
struct trf7970a *trf = spi_get_drvdata(spi); struct trf7970a *trf = spi_get_drvdata(spi);
int ret; int ret;
dev_dbg(dev, "Runtime suspend\n"); dev_dbg(dev, "Resume\n");
if (trf->state != TRF7970A_ST_OFF) { mutex_lock(&trf->lock);
dev_dbg(dev, "Can't suspend - not in OFF state (%d)\n",
trf->state);
return -EBUSY;
}
gpio_set_value(trf->en_gpio, 0); ret = trf7970a_startup(trf);
gpio_set_value(trf->en2_gpio, 0);
ret = regulator_disable(trf->regulator); mutex_unlock(&trf->lock);
if (ret)
dev_err(dev, "%s - Can't disable VIN: %d\n", __func__, ret);
return ret; return ret;
} }
#endif
static int trf7970a_pm_runtime_resume(struct device *dev) #ifdef CONFIG_PM_RUNTIME
static int trf7970a_pm_runtime_suspend(struct device *dev)
{ {
struct spi_device *spi = container_of(dev, struct spi_device, dev); struct spi_device *spi = container_of(dev, struct spi_device, dev);
struct trf7970a *trf = spi_get_drvdata(spi); struct trf7970a *trf = spi_get_drvdata(spi);
int ret; int ret;
dev_dbg(dev, "Runtime resume\n"); dev_dbg(dev, "Runtime suspend\n");
ret = regulator_enable(trf->regulator); mutex_lock(&trf->lock);
if (ret) {
dev_err(dev, "%s - Can't enable VIN: %d\n", __func__, ret);
return ret;
}
usleep_range(5000, 6000); ret = trf7970a_power_down(trf);
gpio_set_value(trf->en2_gpio, 1); mutex_unlock(&trf->lock);
usleep_range(1000, 2000);
gpio_set_value(trf->en_gpio, 1);
usleep_range(20000, 21000); return ret;
}
ret = trf7970a_init(trf); static int trf7970a_pm_runtime_resume(struct device *dev)
if (ret) { {
dev_err(dev, "%s - Can't initialize: %d\n", __func__, ret); struct spi_device *spi = container_of(dev, struct spi_device, dev);
return ret; struct trf7970a *trf = spi_get_drvdata(spi);
} int ret;
pm_runtime_mark_last_busy(dev); dev_dbg(dev, "Runtime resume\n");
return 0; ret = trf7970a_power_up(trf);
if (!ret)
pm_runtime_mark_last_busy(dev);
return ret;
} }
#endif #endif
static const struct dev_pm_ops trf7970a_pm_ops = { static const struct dev_pm_ops trf7970a_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(trf7970a_suspend, trf7970a_resume)
SET_RUNTIME_PM_OPS(trf7970a_pm_runtime_suspend, SET_RUNTIME_PM_OPS(trf7970a_pm_runtime_suspend,
trf7970a_pm_runtime_resume, NULL) trf7970a_pm_runtime_resume, NULL)
}; };
static const struct spi_device_id trf7970a_id_table[] = { static const struct spi_device_id trf7970a_id_table[] = {
{ "trf7970a", TRF7970A_QUIRK_IRQ_STATUS_READ_ERRATA }, { "trf7970a", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(spi, trf7970a_id_table); MODULE_DEVICE_TABLE(spi, trf7970a_id_table);
......
...@@ -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;
......
...@@ -64,10 +64,11 @@ enum nci_state { ...@@ -64,10 +64,11 @@ enum nci_state {
struct nci_dev; struct nci_dev;
struct nci_ops { struct nci_ops {
int (*open)(struct nci_dev *ndev); int (*open)(struct nci_dev *ndev);
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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册