Skip to content

Commit

Permalink
NFC: Sony Port-100 Series driver
Browse files Browse the repository at this point in the history
This adds support for the Sony NFC USB dongle RC-S380, based on the
Port-100 chip. This dongle is an analog frontend and does not implement
the digital layer. This driver uses the nfc_digital module which is an
implementation of the NFC Digital Protocol stack.

This patch is a skeleton. It only registers the dongle against the NFC
digital protocol stack. All NFC digital operation functions are stubbed
out.

Signed-off-by: Thierry Escande <[email protected]>
Cc: Stephen Tiedemann <[email protected]>
Tested-by: Cho, Yu-Chen <[email protected]>
Signed-off-by: Samuel Ortiz <[email protected]>
  • Loading branch information
Thierry Escande authored and Samuel Ortiz committed Oct 7, 2013
1 parent 93ad420 commit 562d4d5
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/nfc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ config NFC_SIM

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/microread/Kconfig"

Expand Down
1 change: 1 addition & 0 deletions drivers/nfc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ obj-$(CONFIG_NFC_PN533) += pn533.o
obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o
obj-$(CONFIG_NFC_SIM) += nfcsim.o
obj-$(CONFIG_NFC_PORT100) += port100.o

ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
187 changes: 187 additions & 0 deletions drivers/nfc/port100.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/*
* Sony NFC Port-100 Series driver
* Copyright (c) 2013, Intel Corporation.
*
* Partly based/Inspired by Stephen Tiedemann's nfcpy
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/

#include <linux/module.h>
#include <linux/usb.h>
#include <net/nfc/digital.h>

#define VERSION "0.1"

#define SONY_VENDOR_ID 0x054c
#define RCS380_PRODUCT_ID 0x06c1

#define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
NFC_PROTO_MIFARE_MASK | \
NFC_PROTO_FELICA_MASK | \
NFC_PROTO_NFC_DEP_MASK)

#define PORT100_CAPABILITIES (NFC_DIGITAL_DRV_CAPS_IN_CRC | \
NFC_DIGITAL_DRV_CAPS_TG_CRC)

struct port100 {
struct nfc_digital_dev *nfc_digital_dev;

int skb_headroom;
int skb_tailroom;

struct usb_device *udev;
struct usb_interface *interface;
};

static void port100_abort_cmd(struct nfc_digital_dev *ddev)
{
}

static int port100_switch_rf(struct nfc_digital_dev *ddev, bool on)
{
return -EOPNOTSUPP;
}

static int port100_in_configure_hw(struct nfc_digital_dev *ddev, int type,
int param)
{
return -EOPNOTSUPP;
}

static int port100_in_send_cmd(struct nfc_digital_dev *ddev,
struct sk_buff *skb, u16 _timeout,
nfc_digital_cmd_complete_t cb, void *arg)
{
return -EOPNOTSUPP;
}

static int port100_tg_configure_hw(struct nfc_digital_dev *ddev, int type,
int param)
{
return -EOPNOTSUPP;
}

static int port100_tg_send_cmd(struct nfc_digital_dev *ddev,
struct sk_buff *skb, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg)
{
return -EOPNOTSUPP;
}

static int port100_listen_mdaa(struct nfc_digital_dev *ddev,
struct digital_tg_mdaa_params *params,
u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg)
{
return -EOPNOTSUPP;
}

static int port100_listen(struct nfc_digital_dev *ddev, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg)
{
return -EOPNOTSUPP;
}

static struct nfc_digital_ops port100_digital_ops = {
.in_configure_hw = port100_in_configure_hw,
.in_send_cmd = port100_in_send_cmd,

.tg_listen_mdaa = port100_listen_mdaa,
.tg_listen = port100_listen,
.tg_configure_hw = port100_tg_configure_hw,
.tg_send_cmd = port100_tg_send_cmd,

.switch_rf = port100_switch_rf,
.abort_cmd = port100_abort_cmd,
};

static const struct usb_device_id port100_table[] = {
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = SONY_VENDOR_ID,
.idProduct = RCS380_PRODUCT_ID,
},
{ }
};
MODULE_DEVICE_TABLE(usb, port100_table);

static int port100_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct port100 *dev;
int rc;

dev = devm_kzalloc(&interface->dev, sizeof(struct port100), GFP_KERNEL);
if (!dev)
return -ENOMEM;

dev->udev = usb_get_dev(interface_to_usbdev(interface));
dev->interface = interface;
usb_set_intfdata(interface, dev);

nfc_info(&interface->dev, "Sony NFC Port-100 Series attached\n");

dev->nfc_digital_dev = nfc_digital_allocate_device(&port100_digital_ops,
PORT100_PROTOCOLS,
PORT100_CAPABILITIES,
dev->skb_headroom,
dev->skb_tailroom);
if (!dev->nfc_digital_dev) {
nfc_err(&interface->dev,
"Could not allocate nfc_digital_dev.\n");
rc = -ENOMEM;
goto error;
}

nfc_digital_set_parent_dev(dev->nfc_digital_dev, &interface->dev);
nfc_digital_set_drvdata(dev->nfc_digital_dev, dev);

rc = nfc_digital_register_device(dev->nfc_digital_dev);
if (rc) {
nfc_err(&interface->dev,
"Could not register digital device.\n");
goto free_nfc_dev;
}

return 0;

free_nfc_dev:
nfc_digital_free_device(dev->nfc_digital_dev);

error:
return rc;
}

static void port100_disconnect(struct usb_interface *interface)
{
struct port100 *dev;

dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);

nfc_digital_unregister_device(dev->nfc_digital_dev);
nfc_digital_free_device(dev->nfc_digital_dev);

nfc_info(&interface->dev, "Sony Port-100 NFC device disconnected");
}

static struct usb_driver port100_driver = {
.name = "port100",
.probe = port100_probe,
.disconnect = port100_disconnect,
.id_table = port100_table,
};

module_usb_driver(port100_driver);

MODULE_DESCRIPTION("NFC Port-100 series usb driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

0 comments on commit 562d4d5

Please sign in to comment.