forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
3 changed files
with
198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |