Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Oleg Zhurakivskyy and committed by
Samuel Ortiz
551e3069 6da8253b

+51
+51
drivers/nfc/nxp-nci/i2c.c
··· 2 2 * I2C link layer for the NXP NCI driver 3 3 * 4 4 * Copyright (C) 2014 NXP Semiconductors All rights reserved. 5 + * Copyright (C) 2012-2015 Intel Corporation. All rights reserved. 5 6 * 6 7 * Authors: Clément Perrochaud <clement.perrochaud@nxp.com> 8 + * Authors: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com> 7 9 * 8 10 * Derived from PN544 device driver: 9 11 * Copyright (C) 2012 Intel Corporation. All rights reserved. ··· 25 23 26 24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 27 25 26 + #include <linux/acpi.h> 28 27 #include <linux/delay.h> 29 28 #include <linux/i2c.h> 30 29 #include <linux/interrupt.h> ··· 51 48 52 49 unsigned int gpio_en; 53 50 unsigned int gpio_fw; 51 + unsigned int gpio_irq; 54 52 55 53 int hard_fault; /* 56 54 * < 0 if hardware error occurred (e.g. i2c err) ··· 312 308 313 309 #endif 314 310 311 + static int nxp_nci_i2c_acpi_config(struct nxp_nci_i2c_phy *phy) 312 + { 313 + struct i2c_client *client = phy->i2c_dev; 314 + struct gpio_desc *gpiod_en, *gpiod_fw, *gpiod_irq; 315 + 316 + gpiod_en = devm_gpiod_get_index(&client->dev, NULL, 2); 317 + gpiod_fw = devm_gpiod_get_index(&client->dev, NULL, 1); 318 + gpiod_irq = devm_gpiod_get_index(&client->dev, NULL, 0); 319 + 320 + if (IS_ERR(gpiod_en) || IS_ERR(gpiod_fw) || IS_ERR(gpiod_irq)) { 321 + nfc_err(&client->dev, "No GPIOs\n"); 322 + return -EINVAL; 323 + } 324 + 325 + gpiod_direction_output(gpiod_en, 0); 326 + gpiod_direction_output(gpiod_fw, 0); 327 + gpiod_direction_input(gpiod_irq); 328 + 329 + client->irq = gpiod_to_irq(gpiod_irq); 330 + if (client->irq < 0) { 331 + nfc_err(&client->dev, "No IRQ\n"); 332 + return -EINVAL; 333 + } 334 + 335 + phy->gpio_en = desc_to_gpio(gpiod_en); 336 + phy->gpio_fw = desc_to_gpio(gpiod_fw); 337 + phy->gpio_irq = desc_to_gpio(gpiod_irq); 338 + 339 + return 0; 340 + } 341 + 315 342 static int nxp_nci_i2c_probe(struct i2c_client *client, 316 343 const struct i2c_device_id *id) 317 344 { ··· 378 343 phy->gpio_en = pdata->gpio_en; 379 344 phy->gpio_fw = pdata->gpio_fw; 380 345 client->irq = pdata->irq; 346 + } else if (ACPI_HANDLE(&client->dev)) { 347 + r = nxp_nci_i2c_acpi_config(phy); 348 + if (r < 0) 349 + goto probe_exit; 350 + goto nci_probe; 381 351 } else { 382 352 nfc_err(&client->dev, "No platform data\n"); 383 353 r = -EINVAL; ··· 399 359 if (r < 0) 400 360 goto probe_exit; 401 361 362 + nci_probe: 402 363 r = nxp_nci_probe(phy, &client->dev, &i2c_phy_ops, 403 364 NXP_NCI_I2C_MAX_PAYLOAD, &phy->ndev); 404 365 if (r < 0) ··· 438 397 }; 439 398 MODULE_DEVICE_TABLE(of, of_nxp_nci_i2c_match); 440 399 400 + #ifdef CONFIG_ACPI 401 + static struct acpi_device_id acpi_id[] = { 402 + { "NXP7471" }, 403 + { }, 404 + }; 405 + MODULE_DEVICE_TABLE(acpi, acpi_id); 406 + #endif 407 + 441 408 static struct i2c_driver nxp_nci_i2c_driver = { 442 409 .driver = { 443 410 .name = NXP_NCI_I2C_DRIVER_NAME, 444 411 .owner = THIS_MODULE, 412 + .acpi_match_table = ACPI_PTR(acpi_id), 445 413 .of_match_table = of_match_ptr(of_nxp_nci_i2c_match), 446 414 }, 447 415 .probe = nxp_nci_i2c_probe, ··· 463 413 MODULE_LICENSE("GPL"); 464 414 MODULE_DESCRIPTION("I2C driver for NXP NCI NFC controllers"); 465 415 MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud@nxp.com>"); 416 + MODULE_AUTHOR("Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>");