Commit e9e1dcda authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'nfc-next'



Andy Shevchenko says:

====================
NFC: nxp-nci: clean up and new device support

Few people reported that some laptops are coming with new ACPI ID for the
devices should be supported by nxp-nci driver.

This series adds new ID (patch 2), cleans up the driver from legacy platform
data and unifies GPIO request for Device Tree and ACPI (patches 3-6), removes
dead or unneeded code (patches 7, 9, 11), constifies ID table (patch 8),
removes comma in terminator line for better maintenance (patch 10) and
rectifies Kconfig entry (patches 12-14).

It also contains a fix for NFC subsystem as suggested by Sedat.

Series has been tested by Sedat.

Changelog v4:
- rebased on top of latest linux-next
- appended cover letter
- elaborated removal of pr_fmt() in the patch 11 (David)
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d24b6c62 8f6920ac
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -11327,7 +11327,6 @@ F: include/net/nfc/
F:	include/uapi/linux/nfc.h
F:	drivers/nfc/
F:	include/linux/platform_data/nfcmrvl.h
F:	include/linux/platform_data/nxp-nci.h
F:	Documentation/devicetree/bindings/net/nfc/

NFS, SUNRPC, AND LOCKD CLIENTS
+3 −4
Original line number Diff line number Diff line
@@ -2,10 +2,9 @@
config NFC_NXP_NCI
	tristate "NXP-NCI NFC driver"
	depends on NFC_NCI
	default n
	---help---
	  Generic core driver for NXP NCI chips such as the NPC100
	  or PN7150 families.
	  Generic core driver for NXP NCI chips such as the NPC100 (PN547),
	  NPC300 (PN548) or PN7150 families.
	  This is a driver based on the NCI NFC kernel layers and
	  will thus not work with NXP libnfc library.

@@ -23,4 +22,4 @@ config NFC_NXP_NCI_I2C

	  To compile this driver as a module, choose m here. The module will
	  be called nxp_nci_i2c.
	  Say Y if unsure.
	  Say N if unsure.
+0 −2
Original line number Diff line number Diff line
@@ -11,10 +11,8 @@
 */

#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/nfc.h>
#include <linux/platform_data/nxp-nci.h>

#include <net/nfc/nci_core.h>

+34 −100
Original line number Diff line number Diff line
@@ -12,8 +12,6 @@
 * Copyright (C) 2012  Intel Corporation. All rights reserved.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/i2c.h>
@@ -21,9 +19,6 @@
#include <linux/module.h>
#include <linux/nfc.h>
#include <linux/gpio/consumer.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/platform_data/nxp-nci.h>
#include <asm/unaligned.h>

#include <net/nfc/nfc.h>
@@ -38,8 +33,8 @@ struct nxp_nci_i2c_phy {
	struct i2c_client *i2c_dev;
	struct nci_dev *ndev;

	unsigned int gpio_en;
	unsigned int gpio_fw;
	struct gpio_desc *gpiod_en;
	struct gpio_desc *gpiod_fw;

	int hard_fault; /*
			 * < 0 if hardware error occurred (e.g. i2c err)
@@ -52,8 +47,8 @@ static int nxp_nci_i2c_set_mode(void *phy_id,
{
	struct nxp_nci_i2c_phy *phy = (struct nxp_nci_i2c_phy *) phy_id;

	gpio_set_value(phy->gpio_fw, (mode == NXP_NCI_MODE_FW) ? 1 : 0);
	gpio_set_value(phy->gpio_en, (mode != NXP_NCI_MODE_COLD) ? 1 : 0);
	gpiod_set_value(phy->gpiod_fw, (mode == NXP_NCI_MODE_FW) ? 1 : 0);
	gpiod_set_value(phy->gpiod_en, (mode != NXP_NCI_MODE_COLD) ? 1 : 0);
	usleep_range(10000, 15000);

	if (mode == NXP_NCI_MODE_COLD)
@@ -250,116 +245,55 @@ exit_irq_none:
	return IRQ_NONE;
}

static int nxp_nci_i2c_parse_devtree(struct i2c_client *client)
{
	struct nxp_nci_i2c_phy *phy = i2c_get_clientdata(client);
	struct device_node *pp;
	int r;

	pp = client->dev.of_node;
	if (!pp)
		return -ENODEV;

	r = of_get_named_gpio(pp, "enable-gpios", 0);
	if (r == -EPROBE_DEFER)
		r = of_get_named_gpio(pp, "enable-gpios", 0);
	if (r < 0) {
		nfc_err(&client->dev, "Failed to get EN gpio, error: %d\n", r);
		return r;
	}
	phy->gpio_en = r;

	r = of_get_named_gpio(pp, "firmware-gpios", 0);
	if (r == -EPROBE_DEFER)
		r = of_get_named_gpio(pp, "firmware-gpios", 0);
	if (r < 0) {
		nfc_err(&client->dev, "Failed to get FW gpio, error: %d\n", r);
		return r;
	}
	phy->gpio_fw = r;

	return 0;
}
static const struct acpi_gpio_params firmware_gpios = { 1, 0, false };
static const struct acpi_gpio_params enable_gpios = { 2, 0, false };

static int nxp_nci_i2c_acpi_config(struct nxp_nci_i2c_phy *phy)
{
	struct i2c_client *client = phy->i2c_dev;
	struct gpio_desc *gpiod_en, *gpiod_fw;

	gpiod_en = devm_gpiod_get_index(&client->dev, NULL, 2, GPIOD_OUT_LOW);
	gpiod_fw = devm_gpiod_get_index(&client->dev, NULL, 1, GPIOD_OUT_LOW);

	if (IS_ERR(gpiod_en) || IS_ERR(gpiod_fw)) {
		nfc_err(&client->dev, "No GPIOs\n");
		return -EINVAL;
	}

	phy->gpio_en = desc_to_gpio(gpiod_en);
	phy->gpio_fw = desc_to_gpio(gpiod_fw);

	return 0;
}
static const struct acpi_gpio_mapping acpi_nxp_nci_gpios[] = {
	{ "enable-gpios", &enable_gpios, 1 },
	{ "firmware-gpios", &firmware_gpios, 1 },
	{ }
};

static int nxp_nci_i2c_probe(struct i2c_client *client,
			    const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct nxp_nci_i2c_phy *phy;
	struct nxp_nci_nfc_platform_data *pdata;
	int r;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
		r = -ENODEV;
		goto probe_exit;
		return -ENODEV;
	}

	phy = devm_kzalloc(&client->dev, sizeof(struct nxp_nci_i2c_phy),
			   GFP_KERNEL);
	if (!phy) {
		r = -ENOMEM;
		goto probe_exit;
	}
	if (!phy)
		return -ENOMEM;

	phy->i2c_dev = client;
	i2c_set_clientdata(client, phy);

	pdata = client->dev.platform_data;
	r = devm_acpi_dev_add_driver_gpios(dev, acpi_nxp_nci_gpios);
	if (r)
		return r;

	if (!pdata && client->dev.of_node) {
		r = nxp_nci_i2c_parse_devtree(client);
		if (r < 0) {
			nfc_err(&client->dev, "Failed to get DT data\n");
			goto probe_exit;
	phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
	if (IS_ERR(phy->gpiod_en)) {
		nfc_err(dev, "Failed to get EN gpio\n");
		return PTR_ERR(phy->gpiod_en);
	}
	} else if (pdata) {
		phy->gpio_en = pdata->gpio_en;
		phy->gpio_fw = pdata->gpio_fw;
	} else if (ACPI_HANDLE(&client->dev)) {
		r = nxp_nci_i2c_acpi_config(phy);
		if (r < 0)
			goto probe_exit;
		goto nci_probe;
	} else {
		nfc_err(&client->dev, "No platform data\n");
		r = -EINVAL;
		goto probe_exit;
	}

	r = devm_gpio_request_one(&phy->i2c_dev->dev, phy->gpio_en,
				  GPIOF_OUT_INIT_LOW, "nxp_nci_en");
	if (r < 0)
		goto probe_exit;

	r = devm_gpio_request_one(&phy->i2c_dev->dev, phy->gpio_fw,
				  GPIOF_OUT_INIT_LOW, "nxp_nci_fw");
	if (r < 0)
		goto probe_exit;
	phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW);
	if (IS_ERR(phy->gpiod_fw)) {
		nfc_err(dev, "Failed to get FW gpio\n");
		return PTR_ERR(phy->gpiod_fw);
	}

nci_probe:
	r = nxp_nci_probe(phy, &client->dev, &i2c_phy_ops,
			  NXP_NCI_I2C_MAX_PAYLOAD, &phy->ndev);
	if (r < 0)
		goto probe_exit;
		return r;

	r = request_threaded_irq(client->irq, NULL,
				 nxp_nci_i2c_irq_thread_fn,
@@ -368,7 +302,6 @@ nci_probe:
	if (r < 0)
		nfc_err(&client->dev, "Unable to register IRQ handler\n");

probe_exit:
	return r;
}

@@ -390,14 +323,15 @@ MODULE_DEVICE_TABLE(i2c, nxp_nci_i2c_id_table);

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

#ifdef CONFIG_ACPI
static struct acpi_device_id acpi_id[] = {
static const struct acpi_device_id acpi_id[] = {
	{ "NXP1001" },
	{ "NXP7471" },
	{ },
	{ }
};
MODULE_DEVICE_TABLE(acpi, acpi_id);
#endif
@@ -406,7 +340,7 @@ static struct i2c_driver nxp_nci_i2c_driver = {
	.driver = {
		   .name = NXP_NCI_I2C_DRIVER_NAME,
		   .acpi_match_table = ACPI_PTR(acpi_id),
		   .of_match_table = of_match_ptr(of_nxp_nci_i2c_match),
		   .of_match_table = of_nxp_nci_i2c_match,
		  },
	.probe = nxp_nci_i2c_probe,
	.id_table = nxp_nci_i2c_id_table,
+0 −1
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@
#include <linux/completion.h>
#include <linux/firmware.h>
#include <linux/nfc.h>
#include <linux/platform_data/nxp-nci.h>

#include <net/nfc/nci_core.h>

Loading