2 * Sony NFC Port-100 Series driver
3 * Copyright (c) 2013, Intel Corporation.
5 * Partly based/Inspired by Stephen Tiedemann's nfcpy
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 #include <linux/module.h>
19 #include <linux/usb.h>
20 #include <net/nfc/digital.h>
24 #define SONY_VENDOR_ID 0x054c
25 #define RCS380_PRODUCT_ID 0x06c1
27 #define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
28 NFC_PROTO_MIFARE_MASK | \
29 NFC_PROTO_FELICA_MASK | \
30 NFC_PROTO_NFC_DEP_MASK)
32 #define PORT100_CAPABILITIES (NFC_DIGITAL_DRV_CAPS_IN_CRC | \
33 NFC_DIGITAL_DRV_CAPS_TG_CRC)
36 struct nfc_digital_dev
*nfc_digital_dev
;
41 struct usb_device
*udev
;
42 struct usb_interface
*interface
;
45 static void port100_abort_cmd(struct nfc_digital_dev
*ddev
)
49 static int port100_switch_rf(struct nfc_digital_dev
*ddev
, bool on
)
54 static int port100_in_configure_hw(struct nfc_digital_dev
*ddev
, int type
,
60 static int port100_in_send_cmd(struct nfc_digital_dev
*ddev
,
61 struct sk_buff
*skb
, u16 _timeout
,
62 nfc_digital_cmd_complete_t cb
, void *arg
)
67 static int port100_tg_configure_hw(struct nfc_digital_dev
*ddev
, int type
,
73 static int port100_tg_send_cmd(struct nfc_digital_dev
*ddev
,
74 struct sk_buff
*skb
, u16 timeout
,
75 nfc_digital_cmd_complete_t cb
, void *arg
)
80 static int port100_listen_mdaa(struct nfc_digital_dev
*ddev
,
81 struct digital_tg_mdaa_params
*params
,
83 nfc_digital_cmd_complete_t cb
, void *arg
)
88 static int port100_listen(struct nfc_digital_dev
*ddev
, u16 timeout
,
89 nfc_digital_cmd_complete_t cb
, void *arg
)
94 static struct nfc_digital_ops port100_digital_ops
= {
95 .in_configure_hw
= port100_in_configure_hw
,
96 .in_send_cmd
= port100_in_send_cmd
,
98 .tg_listen_mdaa
= port100_listen_mdaa
,
99 .tg_listen
= port100_listen
,
100 .tg_configure_hw
= port100_tg_configure_hw
,
101 .tg_send_cmd
= port100_tg_send_cmd
,
103 .switch_rf
= port100_switch_rf
,
104 .abort_cmd
= port100_abort_cmd
,
107 static const struct usb_device_id port100_table
[] = {
108 { .match_flags
= USB_DEVICE_ID_MATCH_DEVICE
,
109 .idVendor
= SONY_VENDOR_ID
,
110 .idProduct
= RCS380_PRODUCT_ID
,
114 MODULE_DEVICE_TABLE(usb
, port100_table
);
116 static int port100_probe(struct usb_interface
*interface
,
117 const struct usb_device_id
*id
)
122 dev
= devm_kzalloc(&interface
->dev
, sizeof(struct port100
), GFP_KERNEL
);
126 dev
->udev
= usb_get_dev(interface_to_usbdev(interface
));
127 dev
->interface
= interface
;
128 usb_set_intfdata(interface
, dev
);
130 nfc_info(&interface
->dev
, "Sony NFC Port-100 Series attached\n");
132 dev
->nfc_digital_dev
= nfc_digital_allocate_device(&port100_digital_ops
,
134 PORT100_CAPABILITIES
,
137 if (!dev
->nfc_digital_dev
) {
138 nfc_err(&interface
->dev
,
139 "Could not allocate nfc_digital_dev.\n");
144 nfc_digital_set_parent_dev(dev
->nfc_digital_dev
, &interface
->dev
);
145 nfc_digital_set_drvdata(dev
->nfc_digital_dev
, dev
);
147 rc
= nfc_digital_register_device(dev
->nfc_digital_dev
);
149 nfc_err(&interface
->dev
,
150 "Could not register digital device.\n");
157 nfc_digital_free_device(dev
->nfc_digital_dev
);
163 static void port100_disconnect(struct usb_interface
*interface
)
167 dev
= usb_get_intfdata(interface
);
168 usb_set_intfdata(interface
, NULL
);
170 nfc_digital_unregister_device(dev
->nfc_digital_dev
);
171 nfc_digital_free_device(dev
->nfc_digital_dev
);
173 nfc_info(&interface
->dev
, "Sony Port-100 NFC device disconnected");
176 static struct usb_driver port100_driver
= {
178 .probe
= port100_probe
,
179 .disconnect
= port100_disconnect
,
180 .id_table
= port100_table
,
183 module_usb_driver(port100_driver
);
185 MODULE_DESCRIPTION("NFC Port-100 series usb driver ver " VERSION
);
186 MODULE_VERSION(VERSION
);
187 MODULE_LICENSE("GPL");