Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df3c2ade authored by John W. Linville's avatar John W. Linville
Browse files


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

"This is the first NFC pull request for the 3.13 kernel.
It's a fairly big one, with the following highlights:

- NFC digital layer implementation: Most NFC chipsets implement the NFC
  digital layer in firmware, but others have more basic functionalities
  and expect the host to implement the digital layer. This layer sits
  below the NFC core.

- Sony's port100 support: This is "soft" NFC USB dongle that expects the
  digital layer to be implemented on the host. This is the first user of
  our NFC digital stack implementation.

- Secure element API: We now provide a netlink API for enabling,
  disabling and discovering NFC attached (embedded or UICC ones) secure
  elements. With some userspace help, this allows us to support NFC
  payments.
  Only the pn544 driver currently supports that API.

- NCI SPI fixes and improvements: In order to support NCI devices over
  SPI, we fixed and improved our NCI/SPI implementation. The currently
  most deployed NFC NCI chipset, Broadcom's bcm2079x, supports that mode
  and we're planning to use our NCI/SPI framework to implement a
  driver for it.

- pn533 fragmentation support in target mode: This was the only missing
  feature from our pn533 impementation. We now support fragmentation in
  both Tx and Rx modes, in target mode."

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parents 444474dd ddc1a70b
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,16 @@ config NFC_SIM


	  If unsure, say N.
	  If unsure, say N.


config NFC_PORT100
	tristate "Sony NFC Port-100 Series USB device support"
	depends on USB
	depends on NFC_DIGITAL
	help
	  This adds support for Sony Port-100 chip based USB devices such as the
	  RC-S380 dongle.

	  If unsure, say N.

source "drivers/nfc/pn544/Kconfig"
source "drivers/nfc/pn544/Kconfig"
source "drivers/nfc/microread/Kconfig"
source "drivers/nfc/microread/Kconfig"


+1 −0
Original line number Original line Diff line number Diff line
@@ -8,5 +8,6 @@ obj-$(CONFIG_NFC_PN533) += pn533.o
obj-$(CONFIG_NFC_WILINK)	+= nfcwilink.o
obj-$(CONFIG_NFC_WILINK)	+= nfcwilink.o
obj-$(CONFIG_NFC_MEI_PHY)	+= mei_phy.o
obj-$(CONFIG_NFC_MEI_PHY)	+= mei_phy.o
obj-$(CONFIG_NFC_SIM)		+= nfcsim.o
obj-$(CONFIG_NFC_SIM)		+= nfcsim.o
obj-$(CONFIG_NFC_PORT100)	+= port100.o


ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
+4 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/nfc.h>
#include <linux/nfc.h>
@@ -60,13 +62,13 @@ int nfc_mei_phy_enable(void *phy_id)


	r = mei_cl_enable_device(phy->device);
	r = mei_cl_enable_device(phy->device);
	if (r < 0) {
	if (r < 0) {
		pr_err("MEI_PHY: Could not enable device\n");
		pr_err("Could not enable device\n");
		return r;
		return r;
	}
	}


	r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
	r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
	if (r) {
	if (r) {
		pr_err("MEY_PHY: Event cb registration failed\n");
		pr_err("Event cb registration failed\n");
		mei_cl_disable_device(phy->device);
		mei_cl_disable_device(phy->device);
		phy->powered = 0;
		phy->powered = 0;


+11 −21
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/delay.h>
@@ -95,12 +97,8 @@ static int check_crc(struct sk_buff *skb)
		crc = crc ^ skb->data[i];
		crc = crc ^ skb->data[i];


	if (crc != skb->data[skb->len-1]) {
	if (crc != skb->data[skb->len-1]) {
		pr_err(MICROREAD_I2C_DRIVER_NAME
		pr_err("CRC error 0x%x != 0x%x\n", crc, skb->data[skb->len-1]);
		       ": CRC error 0x%x != 0x%x\n",
		pr_info("%s: BAD CRC\n", __func__);
		       crc, skb->data[skb->len-1]);

		pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__);

		return -EPERM;
		return -EPERM;
	}
	}


@@ -160,18 +158,15 @@ static int microread_i2c_read(struct microread_i2c_phy *phy,
	u8 tmp[MICROREAD_I2C_LLC_MAX_SIZE - 1];
	u8 tmp[MICROREAD_I2C_LLC_MAX_SIZE - 1];
	struct i2c_client *client = phy->i2c_dev;
	struct i2c_client *client = phy->i2c_dev;


	pr_debug("%s\n", __func__);

	r = i2c_master_recv(client, &len, 1);
	r = i2c_master_recv(client, &len, 1);
	if (r != 1) {
	if (r != 1) {
		dev_err(&client->dev, "cannot read len byte\n");
		nfc_err(&client->dev, "cannot read len byte\n");
		return -EREMOTEIO;
		return -EREMOTEIO;
	}
	}


	if ((len < MICROREAD_I2C_LLC_MIN_SIZE) ||
	if ((len < MICROREAD_I2C_LLC_MIN_SIZE) ||
	    (len > MICROREAD_I2C_LLC_MAX_SIZE)) {
	    (len > MICROREAD_I2C_LLC_MAX_SIZE)) {
		dev_err(&client->dev, "invalid len byte\n");
		nfc_err(&client->dev, "invalid len byte\n");
		pr_err("invalid len byte\n");
		r = -EBADMSG;
		r = -EBADMSG;
		goto flush;
		goto flush;
	}
	}
@@ -228,7 +223,6 @@ static irqreturn_t microread_i2c_irq_thread_fn(int irq, void *phy_id)
	}
	}


	client = phy->i2c_dev;
	client = phy->i2c_dev;
	dev_dbg(&client->dev, "IRQ\n");


	if (phy->hard_fault != 0)
	if (phy->hard_fault != 0)
		return IRQ_HANDLED;
		return IRQ_HANDLED;
@@ -263,20 +257,18 @@ static int microread_i2c_probe(struct i2c_client *client,
		dev_get_platdata(&client->dev);
		dev_get_platdata(&client->dev);
	int r;
	int r;


	dev_dbg(&client->dev, "client %p", client);
	dev_dbg(&client->dev, "client %p\n", client);


	if (!pdata) {
	if (!pdata) {
		dev_err(&client->dev, "client %p: missing platform data",
		nfc_err(&client->dev, "client %p: missing platform data\n",
			client);
			client);
		return -EINVAL;
		return -EINVAL;
	}
	}


	phy = devm_kzalloc(&client->dev, sizeof(struct microread_i2c_phy),
	phy = devm_kzalloc(&client->dev, sizeof(struct microread_i2c_phy),
			   GFP_KERNEL);
			   GFP_KERNEL);
	if (!phy) {
	if (!phy)
		dev_err(&client->dev, "Can't allocate microread phy");
		return -ENOMEM;
		return -ENOMEM;
	}


	i2c_set_clientdata(client, phy);
	i2c_set_clientdata(client, phy);
	phy->i2c_dev = client;
	phy->i2c_dev = client;
@@ -285,7 +277,7 @@ static int microread_i2c_probe(struct i2c_client *client,
				 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
				 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
				 MICROREAD_I2C_DRIVER_NAME, phy);
				 MICROREAD_I2C_DRIVER_NAME, phy);
	if (r) {
	if (r) {
		dev_err(&client->dev, "Unable to register IRQ handler");
		nfc_err(&client->dev, "Unable to register IRQ handler\n");
		return r;
		return r;
	}
	}


@@ -296,7 +288,7 @@ static int microread_i2c_probe(struct i2c_client *client,
	if (r < 0)
	if (r < 0)
		goto err_irq;
		goto err_irq;


	dev_info(&client->dev, "Probed");
	nfc_info(&client->dev, "Probed");


	return 0;
	return 0;


@@ -310,8 +302,6 @@ static int microread_i2c_remove(struct i2c_client *client)
{
{
	struct microread_i2c_phy *phy = i2c_get_clientdata(client);
	struct microread_i2c_phy *phy = i2c_get_clientdata(client);


	dev_dbg(&client->dev, "%s\n", __func__);

	microread_remove(phy->hdev);
	microread_remove(phy->hdev);


	free_irq(client->irq, phy);
	free_irq(client->irq, phy);
+2 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mod_devicetable.h>
#include <linux/nfc.h>
#include <linux/nfc.h>
@@ -59,8 +61,6 @@ static int microread_mei_remove(struct mei_cl_device *device)
{
{
	struct nfc_mei_phy *phy = mei_cl_get_drvdata(device);
	struct nfc_mei_phy *phy = mei_cl_get_drvdata(device);


	pr_info("Removing microread\n");

	microread_remove(phy->hdev);
	microread_remove(phy->hdev);


	nfc_mei_phy_free(phy);
	nfc_mei_phy_free(phy);
Loading