aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nfc
diff options
context:
space:
mode:
authorRobert Dolca <robert.dolca@intel.com>2015-01-26 06:13:37 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2015-01-27 19:09:08 -0500
commit0a5942c8e1480db4b8ee7a8d643e4945ef2f8fed (patch)
treef950d6119efca2ee54835c6af32827e9e5c516c4 /drivers/nfc
parent75dda421a31dc614b8b6502cafd3825e2c72ccf0 (diff)
NFC: Add ACPI support for NXP PN544
Currently there is no support for ACPI. This patch uses the following configuration: - Device id: NXP5440 - Pin mapping: - 0 IRQ pin - 1 enable pin - 2 firmware pin Signed-off-by: Robert Dolca <robert.dolca@intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
-rw-r--r--drivers/nfc/pn544/i2c.c111
1 files changed, 109 insertions, 2 deletions
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
index d9018cda6c7f..cdde745b96bd 100644
--- a/drivers/nfc/pn544/i2c.c
+++ b/drivers/nfc/pn544/i2c.c
@@ -24,11 +24,13 @@
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/of_gpio.h> 25#include <linux/of_gpio.h>
26#include <linux/of_irq.h> 26#include <linux/of_irq.h>
27#include <linux/acpi.h>
27#include <linux/miscdevice.h> 28#include <linux/miscdevice.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
29#include <linux/delay.h> 30#include <linux/delay.h>
30#include <linux/nfc.h> 31#include <linux/nfc.h>
31#include <linux/firmware.h> 32#include <linux/firmware.h>
33#include <linux/gpio/consumer.h>
32#include <linux/platform_data/pn544.h> 34#include <linux/platform_data/pn544.h>
33#include <asm/unaligned.h> 35#include <asm/unaligned.h>
34 36
@@ -41,6 +43,11 @@
41#define PN544_I2C_FRAME_HEADROOM 1 43#define PN544_I2C_FRAME_HEADROOM 1
42#define PN544_I2C_FRAME_TAILROOM 2 44#define PN544_I2C_FRAME_TAILROOM 2
43 45
46/* GPIO names */
47#define PN544_GPIO_NAME_IRQ "pn544_irq"
48#define PN544_GPIO_NAME_FW "pn544_fw"
49#define PN544_GPIO_NAME_EN "pn544_en"
50
44/* framing in HCI mode */ 51/* framing in HCI mode */
45#define PN544_HCI_I2C_LLC_LEN 1 52#define PN544_HCI_I2C_LLC_LEN 1
46#define PN544_HCI_I2C_LLC_CRC 2 53#define PN544_HCI_I2C_LLC_CRC 2
@@ -58,6 +65,13 @@ static struct i2c_device_id pn544_hci_i2c_id_table[] = {
58 65
59MODULE_DEVICE_TABLE(i2c, pn544_hci_i2c_id_table); 66MODULE_DEVICE_TABLE(i2c, pn544_hci_i2c_id_table);
60 67
68static const struct acpi_device_id pn544_hci_i2c_acpi_match[] = {
69 {"NXP5440", 0},
70 {}
71};
72
73MODULE_DEVICE_TABLE(acpi, pn544_hci_i2c_acpi_match);
74
61#define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c" 75#define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c"
62 76
63/* 77/*
@@ -861,6 +875,90 @@ exit_state_wait_secure_write_answer:
861 } 875 }
862} 876}
863 877
878static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client)
879{
880 struct pn544_i2c_phy *phy = i2c_get_clientdata(client);
881 const struct acpi_device_id *id;
882 struct gpio_desc *gpiod_en, *gpiod_irq, *gpiod_fw;
883 struct device *dev;
884 int ret;
885
886 if (!client)
887 return -EINVAL;
888
889 dev = &client->dev;
890
891 /* Match the struct device against a given list of ACPI IDs */
892 id = acpi_match_device(dev->driver->acpi_match_table, dev);
893
894 if (!id)
895 return -ENODEV;
896
897 /* Get EN GPIO from ACPI */
898 gpiod_en = devm_gpiod_get_index(dev, PN544_GPIO_NAME_EN, 1);
899 if (IS_ERR(gpiod_en)) {
900 nfc_err(dev,
901 "Unable to get EN GPIO\n");
902 return -ENODEV;
903 }
904
905 phy->gpio_en = desc_to_gpio(gpiod_en);
906
907 /* Configuration EN GPIO */
908 ret = gpiod_direction_output(gpiod_en, 0);
909 if (ret) {
910 nfc_err(dev, "Fail EN pin direction\n");
911 return ret;
912 }
913
914 /* Get FW GPIO from ACPI */
915 gpiod_fw = devm_gpiod_get_index(dev, PN544_GPIO_NAME_FW, 2);
916 if (IS_ERR(gpiod_fw)) {
917 nfc_err(dev,
918 "Unable to get FW GPIO\n");
919 return -ENODEV;
920 }
921
922 phy->gpio_fw = desc_to_gpio(gpiod_fw);
923
924 /* Configuration FW GPIO */
925 ret = gpiod_direction_output(gpiod_fw, 0);
926 if (ret) {
927 nfc_err(dev, "Fail FW pin direction\n");
928 return ret;
929 }
930
931 /* Get IRQ GPIO */
932 gpiod_irq = devm_gpiod_get_index(dev, PN544_GPIO_NAME_IRQ, 0);
933 if (IS_ERR(gpiod_irq)) {
934 nfc_err(dev,
935 "Unable to get IRQ GPIO\n");
936 return -ENODEV;
937 }
938
939 phy->gpio_irq = desc_to_gpio(gpiod_irq);
940
941 /* Configure IRQ GPIO */
942 ret = gpiod_direction_input(gpiod_irq);
943 if (ret) {
944 nfc_err(dev, "Fail IRQ pin direction\n");
945 return ret;
946 }
947
948 /* Map the pin to an IRQ */
949 ret = gpiod_to_irq(gpiod_irq);
950 if (ret < 0) {
951 nfc_err(dev, "Fail pin IRQ mapping\n");
952 return ret;
953 }
954
955 nfc_info(dev, "GPIO resource, no:%d irq:%d\n",
956 desc_to_gpio(gpiod_irq), ret);
957 client->irq = ret;
958
959 return 0;
960}
961
864#ifdef CONFIG_OF 962#ifdef CONFIG_OF
865 963
866static int pn544_hci_i2c_of_request_resources(struct i2c_client *client) 964static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
@@ -886,7 +984,7 @@ static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
886 phy->gpio_en = ret; 984 phy->gpio_en = ret;
887 985
888 /* Configuration of EN GPIO */ 986 /* Configuration of EN GPIO */
889 ret = gpio_request(phy->gpio_en, "pn544_en"); 987 ret = gpio_request(phy->gpio_en, PN544_GPIO_NAME_EN);
890 if (ret) { 988 if (ret) {
891 nfc_err(&client->dev, "Fail EN pin\n"); 989 nfc_err(&client->dev, "Fail EN pin\n");
892 goto err_dt; 990 goto err_dt;
@@ -908,7 +1006,7 @@ static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
908 phy->gpio_fw = ret; 1006 phy->gpio_fw = ret;
909 1007
910 /* Configuration of FW GPIO */ 1008 /* Configuration of FW GPIO */
911 ret = gpio_request(phy->gpio_fw, "pn544_fw"); 1009 ret = gpio_request(phy->gpio_fw, PN544_GPIO_NAME_FW);
912 if (ret) { 1010 if (ret) {
913 nfc_err(&client->dev, "Fail FW pin\n"); 1011 nfc_err(&client->dev, "Fail FW pin\n");
914 goto err_gpio_en; 1012 goto err_gpio_en;
@@ -1003,6 +1101,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
1003 phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); 1101 phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
1004 phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); 1102 phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
1005 phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); 1103 phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
1104 /* Using ACPI */
1105 } else if (ACPI_HANDLE(&client->dev)) {
1106 r = pn544_hci_i2c_acpi_request_resources(client);
1107 if (r) {
1108 nfc_err(&client->dev,
1109 "Cannot get ACPI data\n");
1110 return r;
1111 }
1006 } else { 1112 } else {
1007 nfc_err(&client->dev, "No platform data\n"); 1113 nfc_err(&client->dev, "No platform data\n");
1008 return -EINVAL; 1114 return -EINVAL;
@@ -1082,6 +1188,7 @@ static struct i2c_driver pn544_hci_i2c_driver = {
1082 .name = PN544_HCI_I2C_DRIVER_NAME, 1188 .name = PN544_HCI_I2C_DRIVER_NAME,
1083 .owner = THIS_MODULE, 1189 .owner = THIS_MODULE,
1084 .of_match_table = of_match_ptr(of_pn544_i2c_match), 1190 .of_match_table = of_match_ptr(of_pn544_i2c_match),
1191 .acpi_match_table = ACPI_PTR(pn544_hci_i2c_acpi_match),
1085 }, 1192 },
1086 .probe = pn544_hci_i2c_probe, 1193 .probe = pn544_hci_i2c_probe,
1087 .id_table = pn544_hci_i2c_id_table, 1194 .id_table = pn544_hci_i2c_id_table,