Skip to content

Commit

Permalink
Merge tag 'nfc-next-3.16-1' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/sameo/nfc-next

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

"NFC: 3.16: First pull request

This is the NFC pull request for 3.16. We have:

- STMicroeectronics st21nfca support. The st21nfca is an HCI chipset and
  thus relies on the HCI stack. This submission provides support for tag
  redaer/writer mode (including Type 5) and device tree bindings.

- PM runtime support and a bunch of bug fixes for TI's trf7970a.

- Device tree support for NXP's pn544. Legacy platform data support is
  obviously kept intact.

- NFC Tag type 4B support to the NFC Digital stack.

- SOCK_RAW type support to the raw NFC socket, and allow NCI
  sniffing from that. This can be extended to report HCI frames and also
  proprietarry ones like e.g. the pn533 ones."

Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
John W. Linville committed May 22, 2014
2 parents 9681047 + 7974728 commit 99abe65
Show file tree
Hide file tree
Showing 28 changed files with 2,368 additions and 139 deletions.
35 changes: 35 additions & 0 deletions Documentation/devicetree/bindings/net/nfc/pn544.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
* NXP Semiconductors PN544 NFC Controller

Required properties:
- compatible: Should be "nxp,pn544-i2c".
- clock-frequency: I�C work frequency.
- reg: address on the bus
- interrupt-parent: phandle for the interrupt gpio controller
- interrupts: GPIO interrupt to which the chip is connected
- enable-gpios: Output GPIO pin used for enabling/disabling the PN544
- firmware-gpios: Output GPIO pin used to enter firmware download mode

Optional SoC Specific Properties:
- pinctrl-names: Contains only one value - "default".
- pintctrl-0: Specifies the pin control groups used for this controller.

Example (for ARM-based BeagleBone with PN544 on I2C2):

&i2c2 {

status = "okay";

pn544: pn544@28 {

compatible = "nxp,pn544-i2c";

reg = <0x28>;
clock-frequency = <400000>;

interrupt-parent = <&gpio1>;
interrupts = <17 GPIO_ACTIVE_HIGH>;

enable-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
firmware-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
};
};
33 changes: 33 additions & 0 deletions Documentation/devicetree/bindings/net/nfc/st21nfca.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
* STMicroelectronics SAS. ST21NFCA NFC Controller

Required properties:
- compatible: Should be "st,st21nfca-i2c".
- clock-frequency: I²C work frequency.
- reg: address on the bus
- interrupt-parent: phandle for the interrupt gpio controller
- interrupts: GPIO interrupt to which the chip is connected
- enable-gpios: Output GPIO pin used for enabling/disabling the ST21NFCA

Optional SoC Specific Properties:
- pinctrl-names: Contains only one value - "default".
- pintctrl-0: Specifies the pin control groups used for this controller.

Example (for ARM-based BeagleBoard xM with ST21NFCA on I2C2):

&i2c2 {

status = "okay";

st21nfca: st21nfca@1 {

compatible = "st,st21nfca_i2c";

reg = <0x01>;
clock-frequency = <400000>;

interrupt-parent = <&gpio5>;
interrupts = <2 IRQ_TYPE_LEVEL_LOW>;

enable-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
};
};
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/net/nfc/trf7970a.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Required properties:
Optional SoC Specific Properties:
- pinctrl-names: Contains only one value - "default".
- pintctrl-0: Specifies the pin control groups used for this controller.
- autosuspend-delay: Specify autosuspend delay in milliseconds.

Example (for ARM-based BeagleBone with TRF7970A on SPI1):

Expand All @@ -29,6 +30,7 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
ti,enable-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>,
<&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>;
autosuspend-delay = <30000>;
status = "okay";
};
};
1 change: 1 addition & 0 deletions drivers/nfc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ config NFC_PORT100
source "drivers/nfc/pn544/Kconfig"
source "drivers/nfc/microread/Kconfig"
source "drivers/nfc/nfcmrvl/Kconfig"
source "drivers/nfc/st21nfca/Kconfig"

endmenu
1 change: 1 addition & 0 deletions drivers/nfc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ obj-$(CONFIG_NFC_SIM) += nfcsim.o
obj-$(CONFIG_NFC_PORT100) += port100.o
obj-$(CONFIG_NFC_MRVL) += nfcmrvl/
obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o
obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/

ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
154 changes: 136 additions & 18 deletions drivers/nfc/pn544/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
Expand Down Expand Up @@ -857,6 +859,92 @@ static void pn544_hci_i2c_fw_work(struct work_struct *work)
}
}

#ifdef CONFIG_OF

static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
{
struct pn544_i2c_phy *phy = i2c_get_clientdata(client);
struct device_node *pp;
int ret;

pp = client->dev.of_node;
if (!pp) {
ret = -ENODEV;
goto err_dt;
}

/* Obtention of EN GPIO from device tree */
ret = of_get_named_gpio(pp, "enable-gpios", 0);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
nfc_err(&client->dev,
"Failed to get EN gpio, error: %d\n", ret);
goto err_dt;
}
phy->gpio_en = ret;

/* Configuration of EN GPIO */
ret = gpio_request(phy->gpio_en, "pn544_en");
if (ret) {
nfc_err(&client->dev, "Fail EN pin\n");
goto err_dt;
}
ret = gpio_direction_output(phy->gpio_en, 0);
if (ret) {
nfc_err(&client->dev, "Fail EN pin direction\n");
goto err_gpio_en;
}

/* Obtention of FW GPIO from device tree */
ret = of_get_named_gpio(pp, "firmware-gpios", 0);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
nfc_err(&client->dev,
"Failed to get FW gpio, error: %d\n", ret);
goto err_gpio_en;
}
phy->gpio_fw = ret;

/* Configuration of FW GPIO */
ret = gpio_request(phy->gpio_fw, "pn544_fw");
if (ret) {
nfc_err(&client->dev, "Fail FW pin\n");
goto err_gpio_en;
}
ret = gpio_direction_output(phy->gpio_fw, 0);
if (ret) {
nfc_err(&client->dev, "Fail FW pin direction\n");
goto err_gpio_fw;
}

/* IRQ */
ret = irq_of_parse_and_map(pp, 0);
if (ret < 0) {
nfc_err(&client->dev,
"Unable to get irq, error: %d\n", ret);
goto err_gpio_fw;
}
client->irq = ret;

return 0;

err_gpio_fw:
gpio_free(phy->gpio_fw);
err_gpio_en:
gpio_free(phy->gpio_en);
err_dt:
return ret;
}

#else

static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
{
return -ENODEV;
}

#endif

static int pn544_hci_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
Expand Down Expand Up @@ -887,25 +975,36 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
i2c_set_clientdata(client, phy);

pdata = client->dev.platform_data;
if (pdata == NULL) {
nfc_err(&client->dev, "No platform data\n");
return -EINVAL;
}

if (pdata->request_resources == NULL) {
nfc_err(&client->dev, "request_resources() missing\n");
return -EINVAL;
}
/* No platform data, using device tree. */
if (!pdata && client->dev.of_node) {
r = pn544_hci_i2c_of_request_resources(client);
if (r) {
nfc_err(&client->dev, "No DT data\n");
return r;
}
/* Using platform data. */
} else if (pdata) {

r = pdata->request_resources(client);
if (r) {
nfc_err(&client->dev, "Cannot get platform resources\n");
return r;
}
if (pdata->request_resources == NULL) {
nfc_err(&client->dev, "request_resources() missing\n");
return -EINVAL;
}

phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
r = pdata->request_resources(client);
if (r) {
nfc_err(&client->dev,
"Cannot get platform resources\n");
return r;
}

phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
} else {
nfc_err(&client->dev, "No platform data\n");
return -EINVAL;
}

pn544_hci_i2c_platform_init(phy);

Expand All @@ -930,8 +1029,12 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
free_irq(client->irq, phy);

err_rti:
if (pdata->free_resources != NULL)
if (!pdata) {
gpio_free(phy->gpio_en);
gpio_free(phy->gpio_fw);
} else if (pdata->free_resources) {
pdata->free_resources();
}

return r;
}
Expand All @@ -953,15 +1056,30 @@ static int pn544_hci_i2c_remove(struct i2c_client *client)
pn544_hci_i2c_disable(phy);

free_irq(client->irq, phy);
if (pdata->free_resources)

/* No platform data, GPIOs have been requested by this driver */
if (!pdata) {
gpio_free(phy->gpio_en);
gpio_free(phy->gpio_fw);
/* Using platform data */
} else if (pdata->free_resources) {
pdata->free_resources();
}

return 0;
}

static const struct of_device_id of_pn544_i2c_match[] = {
{ .compatible = "nxp,pn544-i2c", },
{},
};
MODULE_DEVICE_TABLE(of, of_pn544_i2c_match);

static struct i2c_driver pn544_hci_i2c_driver = {
.driver = {
.name = PN544_HCI_I2C_DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_pn544_i2c_match),
},
.probe = pn544_hci_i2c_probe,
.id_table = pn544_hci_i2c_id_table,
Expand Down
23 changes: 23 additions & 0 deletions drivers/nfc/st21nfca/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
config NFC_ST21NFCA
tristate "STMicroelectronics ST21NFCA NFC driver"
depends on NFC_HCI
select CRC_CCITT
default n
---help---
STMicroelectronics ST21NFCA core driver. It implements the chipset
HCI logic and hooks into the NFC kernel APIs. Physical layers will
register against it.

To compile this driver as a module, choose m here. The module will
be called st21nfca.
Say N if unsure.

config NFC_ST21NFCA_I2C
tristate "NFC ST21NFCA i2c support"
depends on NFC_ST21NFCA && I2C && NFC_SHDLC
---help---
This module adds support for the STMicroelectronics st21nfca i2c interface.
Select this if your platform is using the i2c bus.

If you choose to build a module, it'll be called st21nfca_i2c.
Say N if unsure.
8 changes: 8 additions & 0 deletions drivers/nfc/st21nfca/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#
# Makefile for ST21NFCA HCI based NFC driver
#

st21nfca_i2c-objs = i2c.o

obj-$(CONFIG_NFC_ST21NFCA) += st21nfca.o
obj-$(CONFIG_NFC_ST21NFCA_I2C) += st21nfca_i2c.o
Loading

0 comments on commit 99abe65

Please sign in to comment.