diff options
author | Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com> | 2015-05-25 06:55:13 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2015-06-08 17:15:30 -0400 |
commit | 551e306905ef2075b3ad03390ef3e19bd1739598 (patch) | |
tree | a4b07bd3b2d959fe26bc07aaeb202b053ccc3f9f | |
parent | 6da8253bdd3945b81377e4908d6d395a9956f8af (diff) |
NFC: nxp-nci_i2c: Add support for enumerating through ACPI
Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/nfc/nxp-nci/i2c.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index 17bd67dbebf0..2c58bd32c991 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c | |||
@@ -2,8 +2,10 @@ | |||
2 | * I2C link layer for the NXP NCI driver | 2 | * I2C link layer for the NXP NCI driver |
3 | * | 3 | * |
4 | * Copyright (C) 2014 NXP Semiconductors All rights reserved. | 4 | * Copyright (C) 2014 NXP Semiconductors All rights reserved. |
5 | * Copyright (C) 2012-2015 Intel Corporation. All rights reserved. | ||
5 | * | 6 | * |
6 | * Authors: Clément Perrochaud <clement.perrochaud@nxp.com> | 7 | * Authors: Clément Perrochaud <clement.perrochaud@nxp.com> |
8 | * Authors: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com> | ||
7 | * | 9 | * |
8 | * Derived from PN544 device driver: | 10 | * Derived from PN544 device driver: |
9 | * Copyright (C) 2012 Intel Corporation. All rights reserved. | 11 | * Copyright (C) 2012 Intel Corporation. All rights reserved. |
@@ -23,6 +25,7 @@ | |||
23 | 25 | ||
24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
25 | 27 | ||
28 | #include <linux/acpi.h> | ||
26 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
27 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
28 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
@@ -48,6 +51,7 @@ struct nxp_nci_i2c_phy { | |||
48 | 51 | ||
49 | unsigned int gpio_en; | 52 | unsigned int gpio_en; |
50 | unsigned int gpio_fw; | 53 | unsigned int gpio_fw; |
54 | unsigned int gpio_irq; | ||
51 | 55 | ||
52 | int hard_fault; /* | 56 | int hard_fault; /* |
53 | * < 0 if hardware error occurred (e.g. i2c err) | 57 | * < 0 if hardware error occurred (e.g. i2c err) |
@@ -308,6 +312,37 @@ static int nxp_nci_i2c_parse_devtree(struct i2c_client *client) | |||
308 | 312 | ||
309 | #endif | 313 | #endif |
310 | 314 | ||
315 | static int nxp_nci_i2c_acpi_config(struct nxp_nci_i2c_phy *phy) | ||
316 | { | ||
317 | struct i2c_client *client = phy->i2c_dev; | ||
318 | struct gpio_desc *gpiod_en, *gpiod_fw, *gpiod_irq; | ||
319 | |||
320 | gpiod_en = devm_gpiod_get_index(&client->dev, NULL, 2); | ||
321 | gpiod_fw = devm_gpiod_get_index(&client->dev, NULL, 1); | ||
322 | gpiod_irq = devm_gpiod_get_index(&client->dev, NULL, 0); | ||
323 | |||
324 | if (IS_ERR(gpiod_en) || IS_ERR(gpiod_fw) || IS_ERR(gpiod_irq)) { | ||
325 | nfc_err(&client->dev, "No GPIOs\n"); | ||
326 | return -EINVAL; | ||
327 | } | ||
328 | |||
329 | gpiod_direction_output(gpiod_en, 0); | ||
330 | gpiod_direction_output(gpiod_fw, 0); | ||
331 | gpiod_direction_input(gpiod_irq); | ||
332 | |||
333 | client->irq = gpiod_to_irq(gpiod_irq); | ||
334 | if (client->irq < 0) { | ||
335 | nfc_err(&client->dev, "No IRQ\n"); | ||
336 | return -EINVAL; | ||
337 | } | ||
338 | |||
339 | phy->gpio_en = desc_to_gpio(gpiod_en); | ||
340 | phy->gpio_fw = desc_to_gpio(gpiod_fw); | ||
341 | phy->gpio_irq = desc_to_gpio(gpiod_irq); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
311 | static int nxp_nci_i2c_probe(struct i2c_client *client, | 346 | static int nxp_nci_i2c_probe(struct i2c_client *client, |
312 | const struct i2c_device_id *id) | 347 | const struct i2c_device_id *id) |
313 | { | 348 | { |
@@ -343,6 +378,11 @@ static int nxp_nci_i2c_probe(struct i2c_client *client, | |||
343 | phy->gpio_en = pdata->gpio_en; | 378 | phy->gpio_en = pdata->gpio_en; |
344 | phy->gpio_fw = pdata->gpio_fw; | 379 | phy->gpio_fw = pdata->gpio_fw; |
345 | client->irq = pdata->irq; | 380 | client->irq = pdata->irq; |
381 | } else if (ACPI_HANDLE(&client->dev)) { | ||
382 | r = nxp_nci_i2c_acpi_config(phy); | ||
383 | if (r < 0) | ||
384 | goto probe_exit; | ||
385 | goto nci_probe; | ||
346 | } else { | 386 | } else { |
347 | nfc_err(&client->dev, "No platform data\n"); | 387 | nfc_err(&client->dev, "No platform data\n"); |
348 | r = -EINVAL; | 388 | r = -EINVAL; |
@@ -359,6 +399,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client, | |||
359 | if (r < 0) | 399 | if (r < 0) |
360 | goto probe_exit; | 400 | goto probe_exit; |
361 | 401 | ||
402 | nci_probe: | ||
362 | r = nxp_nci_probe(phy, &client->dev, &i2c_phy_ops, | 403 | r = nxp_nci_probe(phy, &client->dev, &i2c_phy_ops, |
363 | NXP_NCI_I2C_MAX_PAYLOAD, &phy->ndev); | 404 | NXP_NCI_I2C_MAX_PAYLOAD, &phy->ndev); |
364 | if (r < 0) | 405 | if (r < 0) |
@@ -397,10 +438,19 @@ static const struct of_device_id of_nxp_nci_i2c_match[] = { | |||
397 | }; | 438 | }; |
398 | MODULE_DEVICE_TABLE(of, of_nxp_nci_i2c_match); | 439 | MODULE_DEVICE_TABLE(of, of_nxp_nci_i2c_match); |
399 | 440 | ||
441 | #ifdef CONFIG_ACPI | ||
442 | static struct acpi_device_id acpi_id[] = { | ||
443 | { "NXP7471" }, | ||
444 | { }, | ||
445 | }; | ||
446 | MODULE_DEVICE_TABLE(acpi, acpi_id); | ||
447 | #endif | ||
448 | |||
400 | static struct i2c_driver nxp_nci_i2c_driver = { | 449 | static struct i2c_driver nxp_nci_i2c_driver = { |
401 | .driver = { | 450 | .driver = { |
402 | .name = NXP_NCI_I2C_DRIVER_NAME, | 451 | .name = NXP_NCI_I2C_DRIVER_NAME, |
403 | .owner = THIS_MODULE, | 452 | .owner = THIS_MODULE, |
453 | .acpi_match_table = ACPI_PTR(acpi_id), | ||
404 | .of_match_table = of_match_ptr(of_nxp_nci_i2c_match), | 454 | .of_match_table = of_match_ptr(of_nxp_nci_i2c_match), |
405 | }, | 455 | }, |
406 | .probe = nxp_nci_i2c_probe, | 456 | .probe = nxp_nci_i2c_probe, |
@@ -413,3 +463,4 @@ module_i2c_driver(nxp_nci_i2c_driver); | |||
413 | MODULE_LICENSE("GPL"); | 463 | MODULE_LICENSE("GPL"); |
414 | MODULE_DESCRIPTION("I2C driver for NXP NCI NFC controllers"); | 464 | MODULE_DESCRIPTION("I2C driver for NXP NCI NFC controllers"); |
415 | MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud@nxp.com>"); | 465 | MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud@nxp.com>"); |
466 | MODULE_AUTHOR("Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>"); | ||