2 * Marvell NFC-over-USB driver: USB interface related functions
4 * Copyright (C) 2014, Marvell International Ltd.
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available on the worldwide web at
11 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
14 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
15 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
16 * this warranty disclaimer.
19 #include <linux/module.h>
20 #include <linux/usb.h>
21 #include <linux/nfc.h>
22 #include <net/nfc/nci.h>
23 #include <net/nfc/nci_core.h>
26 static struct usb_device_id nfcmrvl_table
[] = {
27 { USB_DEVICE_AND_INTERFACE_INFO(0x1286, 0x2046,
28 USB_CLASS_VENDOR_SPEC
, 4, 1) },
29 { } /* Terminating entry */
32 MODULE_DEVICE_TABLE(usb
, nfcmrvl_table
);
34 #define NFCMRVL_USB_BULK_RUNNING 1
35 #define NFCMRVL_USB_SUSPENDING 2
37 struct nfcmrvl_usb_drv_data
{
38 struct usb_device
*udev
;
39 struct usb_interface
*intf
;
41 struct work_struct waker
;
42 struct usb_anchor tx_anchor
;
43 struct usb_anchor bulk_anchor
;
44 struct usb_anchor deferred
;
46 /* protects tx_in_flight */
48 struct usb_endpoint_descriptor
*bulk_tx_ep
;
49 struct usb_endpoint_descriptor
*bulk_rx_ep
;
51 struct nfcmrvl_private
*priv
;
54 static int nfcmrvl_inc_tx(struct nfcmrvl_usb_drv_data
*drv_data
)
59 spin_lock_irqsave(&drv_data
->txlock
, flags
);
60 rv
= test_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
62 drv_data
->tx_in_flight
++;
63 spin_unlock_irqrestore(&drv_data
->txlock
, flags
);
68 static void nfcmrvl_bulk_complete(struct urb
*urb
)
70 struct nfcmrvl_usb_drv_data
*drv_data
= urb
->context
;
74 dev_dbg(&drv_data
->udev
->dev
, "urb %p status %d count %d\n",
75 urb
, urb
->status
, urb
->actual_length
);
77 if (!test_bit(NFCMRVL_NCI_RUNNING
, &drv_data
->flags
))
81 skb
= nci_skb_alloc(drv_data
->priv
->ndev
, urb
->actual_length
,
84 nfc_err(&drv_data
->udev
->dev
, "failed to alloc mem\n");
86 skb_put_data(skb
, urb
->transfer_buffer
,
88 if (nfcmrvl_nci_recv_frame(drv_data
->priv
, skb
) < 0)
89 nfc_err(&drv_data
->udev
->dev
,
90 "corrupted Rx packet\n");
94 if (!test_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
))
97 usb_anchor_urb(urb
, &drv_data
->bulk_anchor
);
98 usb_mark_last_busy(drv_data
->udev
);
100 err
= usb_submit_urb(urb
, GFP_ATOMIC
);
102 /* -EPERM: urb is being killed;
103 * -ENODEV: device got disconnected
105 if (err
!= -EPERM
&& err
!= -ENODEV
)
106 nfc_err(&drv_data
->udev
->dev
,
107 "urb %p failed to resubmit (%d)\n", urb
, -err
);
108 usb_unanchor_urb(urb
);
113 nfcmrvl_submit_bulk_urb(struct nfcmrvl_usb_drv_data
*drv_data
, gfp_t mem_flags
)
118 int err
, size
= NFCMRVL_NCI_MAX_EVENT_SIZE
;
120 if (!drv_data
->bulk_rx_ep
)
123 urb
= usb_alloc_urb(0, mem_flags
);
127 buf
= kmalloc(size
, mem_flags
);
133 pipe
= usb_rcvbulkpipe(drv_data
->udev
,
134 drv_data
->bulk_rx_ep
->bEndpointAddress
);
136 usb_fill_bulk_urb(urb
, drv_data
->udev
, pipe
, buf
, size
,
137 nfcmrvl_bulk_complete
, drv_data
);
139 urb
->transfer_flags
|= URB_FREE_BUFFER
;
141 usb_mark_last_busy(drv_data
->udev
);
142 usb_anchor_urb(urb
, &drv_data
->bulk_anchor
);
144 err
= usb_submit_urb(urb
, mem_flags
);
146 if (err
!= -EPERM
&& err
!= -ENODEV
)
147 nfc_err(&drv_data
->udev
->dev
,
148 "urb %p submission failed (%d)\n", urb
, -err
);
149 usb_unanchor_urb(urb
);
157 static void nfcmrvl_tx_complete(struct urb
*urb
)
159 struct sk_buff
*skb
= urb
->context
;
160 struct nci_dev
*ndev
= (struct nci_dev
*)skb
->dev
;
161 struct nfcmrvl_private
*priv
= nci_get_drvdata(ndev
);
162 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
165 nfc_info(priv
->dev
, "urb %p status %d count %d\n",
166 urb
, urb
->status
, urb
->actual_length
);
168 spin_lock_irqsave(&drv_data
->txlock
, flags
);
169 drv_data
->tx_in_flight
--;
170 spin_unlock_irqrestore(&drv_data
->txlock
, flags
);
172 kfree(urb
->setup_packet
);
176 static int nfcmrvl_usb_nci_open(struct nfcmrvl_private
*priv
)
178 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
181 err
= usb_autopm_get_interface(drv_data
->intf
);
185 drv_data
->intf
->needs_remote_wakeup
= 1;
187 err
= nfcmrvl_submit_bulk_urb(drv_data
, GFP_KERNEL
);
191 set_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
);
192 nfcmrvl_submit_bulk_urb(drv_data
, GFP_KERNEL
);
194 usb_autopm_put_interface(drv_data
->intf
);
198 usb_autopm_put_interface(drv_data
->intf
);
202 static void nfcmrvl_usb_stop_traffic(struct nfcmrvl_usb_drv_data
*drv_data
)
204 usb_kill_anchored_urbs(&drv_data
->bulk_anchor
);
207 static int nfcmrvl_usb_nci_close(struct nfcmrvl_private
*priv
)
209 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
212 cancel_work_sync(&drv_data
->waker
);
214 clear_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
);
216 nfcmrvl_usb_stop_traffic(drv_data
);
217 usb_kill_anchored_urbs(&drv_data
->tx_anchor
);
218 err
= usb_autopm_get_interface(drv_data
->intf
);
222 drv_data
->intf
->needs_remote_wakeup
= 0;
223 usb_autopm_put_interface(drv_data
->intf
);
226 usb_scuttle_anchored_urbs(&drv_data
->deferred
);
230 static int nfcmrvl_usb_nci_send(struct nfcmrvl_private
*priv
,
233 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
238 if (!drv_data
->bulk_tx_ep
)
241 urb
= usb_alloc_urb(0, GFP_ATOMIC
);
245 pipe
= usb_sndbulkpipe(drv_data
->udev
,
246 drv_data
->bulk_tx_ep
->bEndpointAddress
);
248 usb_fill_bulk_urb(urb
, drv_data
->udev
, pipe
, skb
->data
, skb
->len
,
249 nfcmrvl_tx_complete
, skb
);
251 err
= nfcmrvl_inc_tx(drv_data
);
253 usb_anchor_urb(urb
, &drv_data
->deferred
);
254 schedule_work(&drv_data
->waker
);
259 usb_anchor_urb(urb
, &drv_data
->tx_anchor
);
261 err
= usb_submit_urb(urb
, GFP_ATOMIC
);
263 if (err
!= -EPERM
&& err
!= -ENODEV
)
264 nfc_err(&drv_data
->udev
->dev
,
265 "urb %p submission failed (%d)\n", urb
, -err
);
266 kfree(urb
->setup_packet
);
267 usb_unanchor_urb(urb
);
269 usb_mark_last_busy(drv_data
->udev
);
277 static struct nfcmrvl_if_ops usb_ops
= {
278 .nci_open
= nfcmrvl_usb_nci_open
,
279 .nci_close
= nfcmrvl_usb_nci_close
,
280 .nci_send
= nfcmrvl_usb_nci_send
,
283 static void nfcmrvl_waker(struct work_struct
*work
)
285 struct nfcmrvl_usb_drv_data
*drv_data
=
286 container_of(work
, struct nfcmrvl_usb_drv_data
, waker
);
289 err
= usb_autopm_get_interface(drv_data
->intf
);
293 usb_autopm_put_interface(drv_data
->intf
);
296 static int nfcmrvl_probe(struct usb_interface
*intf
,
297 const struct usb_device_id
*id
)
299 struct usb_endpoint_descriptor
*ep_desc
;
300 struct nfcmrvl_usb_drv_data
*drv_data
;
301 struct nfcmrvl_private
*priv
;
303 struct usb_device
*udev
= interface_to_usbdev(intf
);
304 struct nfcmrvl_platform_data config
;
306 /* No configuration for USB */
307 memset(&config
, 0, sizeof(config
));
308 config
.reset_n_io
= -EINVAL
;
310 nfc_info(&udev
->dev
, "intf %p id %p\n", intf
, id
);
312 drv_data
= devm_kzalloc(&intf
->dev
, sizeof(*drv_data
), GFP_KERNEL
);
316 for (i
= 0; i
< intf
->cur_altsetting
->desc
.bNumEndpoints
; i
++) {
317 ep_desc
= &intf
->cur_altsetting
->endpoint
[i
].desc
;
319 if (!drv_data
->bulk_tx_ep
&&
320 usb_endpoint_is_bulk_out(ep_desc
)) {
321 drv_data
->bulk_tx_ep
= ep_desc
;
325 if (!drv_data
->bulk_rx_ep
&&
326 usb_endpoint_is_bulk_in(ep_desc
)) {
327 drv_data
->bulk_rx_ep
= ep_desc
;
332 if (!drv_data
->bulk_tx_ep
|| !drv_data
->bulk_rx_ep
)
335 drv_data
->udev
= udev
;
336 drv_data
->intf
= intf
;
338 INIT_WORK(&drv_data
->waker
, nfcmrvl_waker
);
339 spin_lock_init(&drv_data
->txlock
);
341 init_usb_anchor(&drv_data
->tx_anchor
);
342 init_usb_anchor(&drv_data
->bulk_anchor
);
343 init_usb_anchor(&drv_data
->deferred
);
345 priv
= nfcmrvl_nci_register_dev(NFCMRVL_PHY_USB
, drv_data
, &usb_ops
,
346 &intf
->dev
, &config
);
348 return PTR_ERR(priv
);
350 drv_data
->priv
= priv
;
351 drv_data
->priv
->support_fw_dnld
= false;
353 usb_set_intfdata(intf
, drv_data
);
358 static void nfcmrvl_disconnect(struct usb_interface
*intf
)
360 struct nfcmrvl_usb_drv_data
*drv_data
= usb_get_intfdata(intf
);
365 nfc_info(&drv_data
->udev
->dev
, "intf %p\n", intf
);
367 nfcmrvl_nci_unregister_dev(drv_data
->priv
);
369 usb_set_intfdata(drv_data
->intf
, NULL
);
373 static int nfcmrvl_suspend(struct usb_interface
*intf
, pm_message_t message
)
375 struct nfcmrvl_usb_drv_data
*drv_data
= usb_get_intfdata(intf
);
377 nfc_info(&drv_data
->udev
->dev
, "intf %p\n", intf
);
379 if (drv_data
->suspend_count
++)
382 spin_lock_irq(&drv_data
->txlock
);
383 if (!(PMSG_IS_AUTO(message
) && drv_data
->tx_in_flight
)) {
384 set_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
385 spin_unlock_irq(&drv_data
->txlock
);
387 spin_unlock_irq(&drv_data
->txlock
);
388 drv_data
->suspend_count
--;
392 nfcmrvl_usb_stop_traffic(drv_data
);
393 usb_kill_anchored_urbs(&drv_data
->tx_anchor
);
398 static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data
*drv_data
)
403 while ((urb
= usb_get_from_anchor(&drv_data
->deferred
))) {
404 err
= usb_submit_urb(urb
, GFP_ATOMIC
);
408 drv_data
->tx_in_flight
++;
410 usb_scuttle_anchored_urbs(&drv_data
->deferred
);
413 static int nfcmrvl_resume(struct usb_interface
*intf
)
415 struct nfcmrvl_usb_drv_data
*drv_data
= usb_get_intfdata(intf
);
418 nfc_info(&drv_data
->udev
->dev
, "intf %p\n", intf
);
420 if (--drv_data
->suspend_count
)
423 if (!test_bit(NFCMRVL_NCI_RUNNING
, &drv_data
->flags
))
426 if (test_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
)) {
427 err
= nfcmrvl_submit_bulk_urb(drv_data
, GFP_NOIO
);
429 clear_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
);
433 nfcmrvl_submit_bulk_urb(drv_data
, GFP_NOIO
);
436 spin_lock_irq(&drv_data
->txlock
);
437 nfcmrvl_play_deferred(drv_data
);
438 clear_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
439 spin_unlock_irq(&drv_data
->txlock
);
444 usb_scuttle_anchored_urbs(&drv_data
->deferred
);
446 spin_lock_irq(&drv_data
->txlock
);
447 clear_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
448 spin_unlock_irq(&drv_data
->txlock
);
454 static struct usb_driver nfcmrvl_usb_driver
= {
456 .probe
= nfcmrvl_probe
,
457 .disconnect
= nfcmrvl_disconnect
,
459 .suspend
= nfcmrvl_suspend
,
460 .resume
= nfcmrvl_resume
,
461 .reset_resume
= nfcmrvl_resume
,
463 .id_table
= nfcmrvl_table
,
464 .supports_autosuspend
= 1,
465 .disable_hub_initiated_lpm
= 1,
468 module_usb_driver(nfcmrvl_usb_driver
);
470 MODULE_AUTHOR("Marvell International Ltd.");
471 MODULE_DESCRIPTION("Marvell NFC-over-USB driver");
472 MODULE_LICENSE("GPL v2");