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>
28 static struct usb_device_id nfcmrvl_table
[] = {
29 { USB_DEVICE_AND_INTERFACE_INFO(0x1286, 0x2046,
30 USB_CLASS_VENDOR_SPEC
, 4, 1) },
31 { } /* Terminating entry */
34 MODULE_DEVICE_TABLE(usb
, nfcmrvl_table
);
36 #define NFCMRVL_USB_BULK_RUNNING 1
37 #define NFCMRVL_USB_SUSPENDING 2
39 struct nfcmrvl_usb_drv_data
{
40 struct usb_device
*udev
;
41 struct usb_interface
*intf
;
43 struct work_struct waker
;
44 struct usb_anchor tx_anchor
;
45 struct usb_anchor bulk_anchor
;
46 struct usb_anchor deferred
;
48 /* protects tx_in_flight */
50 struct usb_endpoint_descriptor
*bulk_tx_ep
;
51 struct usb_endpoint_descriptor
*bulk_rx_ep
;
53 struct nfcmrvl_private
*priv
;
56 static int nfcmrvl_inc_tx(struct nfcmrvl_usb_drv_data
*drv_data
)
61 spin_lock_irqsave(&drv_data
->txlock
, flags
);
62 rv
= test_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
64 drv_data
->tx_in_flight
++;
65 spin_unlock_irqrestore(&drv_data
->txlock
, flags
);
70 static void nfcmrvl_bulk_complete(struct urb
*urb
)
72 struct nfcmrvl_usb_drv_data
*drv_data
= urb
->context
;
76 dev_dbg(&drv_data
->udev
->dev
, "urb %p status %d count %d\n",
77 urb
, urb
->status
, urb
->actual_length
);
79 if (!test_bit(NFCMRVL_NCI_RUNNING
, &drv_data
->flags
))
83 skb
= nci_skb_alloc(drv_data
->priv
->ndev
, urb
->actual_length
,
86 nfc_err(&drv_data
->udev
->dev
, "failed to alloc mem\n");
88 memcpy(skb_put(skb
, urb
->actual_length
),
89 urb
->transfer_buffer
, urb
->actual_length
);
90 if (nfcmrvl_nci_recv_frame(drv_data
->priv
, skb
) < 0)
91 nfc_err(&drv_data
->udev
->dev
,
92 "corrupted Rx packet\n");
96 if (!test_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
))
99 usb_anchor_urb(urb
, &drv_data
->bulk_anchor
);
100 usb_mark_last_busy(drv_data
->udev
);
102 err
= usb_submit_urb(urb
, GFP_ATOMIC
);
104 /* -EPERM: urb is being killed;
105 * -ENODEV: device got disconnected
107 if (err
!= -EPERM
&& err
!= -ENODEV
)
108 nfc_err(&drv_data
->udev
->dev
,
109 "urb %p failed to resubmit (%d)\n", urb
, -err
);
110 usb_unanchor_urb(urb
);
115 nfcmrvl_submit_bulk_urb(struct nfcmrvl_usb_drv_data
*drv_data
, gfp_t mem_flags
)
120 int err
, size
= NFCMRVL_NCI_MAX_EVENT_SIZE
;
122 if (!drv_data
->bulk_rx_ep
)
125 urb
= usb_alloc_urb(0, mem_flags
);
129 buf
= kmalloc(size
, mem_flags
);
135 pipe
= usb_rcvbulkpipe(drv_data
->udev
,
136 drv_data
->bulk_rx_ep
->bEndpointAddress
);
138 usb_fill_bulk_urb(urb
, drv_data
->udev
, pipe
, buf
, size
,
139 nfcmrvl_bulk_complete
, drv_data
);
141 urb
->transfer_flags
|= URB_FREE_BUFFER
;
143 usb_mark_last_busy(drv_data
->udev
);
144 usb_anchor_urb(urb
, &drv_data
->bulk_anchor
);
146 err
= usb_submit_urb(urb
, mem_flags
);
148 if (err
!= -EPERM
&& err
!= -ENODEV
)
149 nfc_err(&drv_data
->udev
->dev
,
150 "urb %p submission failed (%d)\n", urb
, -err
);
151 usb_unanchor_urb(urb
);
159 static void nfcmrvl_tx_complete(struct urb
*urb
)
161 struct sk_buff
*skb
= urb
->context
;
162 struct nci_dev
*ndev
= (struct nci_dev
*)skb
->dev
;
163 struct nfcmrvl_private
*priv
= nci_get_drvdata(ndev
);
164 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
166 nfc_info(priv
->dev
, "urb %p status %d count %d\n",
167 urb
, urb
->status
, urb
->actual_length
);
169 spin_lock(&drv_data
->txlock
);
170 drv_data
->tx_in_flight
--;
171 spin_unlock(&drv_data
->txlock
);
173 kfree(urb
->setup_packet
);
177 static int nfcmrvl_usb_nci_open(struct nfcmrvl_private
*priv
)
179 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
182 err
= usb_autopm_get_interface(drv_data
->intf
);
186 drv_data
->intf
->needs_remote_wakeup
= 1;
188 err
= nfcmrvl_submit_bulk_urb(drv_data
, GFP_KERNEL
);
192 set_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
);
193 nfcmrvl_submit_bulk_urb(drv_data
, GFP_KERNEL
);
195 usb_autopm_put_interface(drv_data
->intf
);
199 usb_autopm_put_interface(drv_data
->intf
);
203 static void nfcmrvl_usb_stop_traffic(struct nfcmrvl_usb_drv_data
*drv_data
)
205 usb_kill_anchored_urbs(&drv_data
->bulk_anchor
);
208 static int nfcmrvl_usb_nci_close(struct nfcmrvl_private
*priv
)
210 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
213 cancel_work_sync(&drv_data
->waker
);
215 clear_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
);
217 nfcmrvl_usb_stop_traffic(drv_data
);
218 usb_kill_anchored_urbs(&drv_data
->tx_anchor
);
219 err
= usb_autopm_get_interface(drv_data
->intf
);
223 drv_data
->intf
->needs_remote_wakeup
= 0;
224 usb_autopm_put_interface(drv_data
->intf
);
227 usb_scuttle_anchored_urbs(&drv_data
->deferred
);
231 static int nfcmrvl_usb_nci_send(struct nfcmrvl_private
*priv
,
234 struct nfcmrvl_usb_drv_data
*drv_data
= priv
->drv_data
;
239 if (!drv_data
->bulk_tx_ep
)
242 urb
= usb_alloc_urb(0, GFP_ATOMIC
);
246 pipe
= usb_sndbulkpipe(drv_data
->udev
,
247 drv_data
->bulk_tx_ep
->bEndpointAddress
);
249 usb_fill_bulk_urb(urb
, drv_data
->udev
, pipe
, skb
->data
, skb
->len
,
250 nfcmrvl_tx_complete
, skb
);
252 err
= nfcmrvl_inc_tx(drv_data
);
254 usb_anchor_urb(urb
, &drv_data
->deferred
);
255 schedule_work(&drv_data
->waker
);
260 usb_anchor_urb(urb
, &drv_data
->tx_anchor
);
262 err
= usb_submit_urb(urb
, GFP_ATOMIC
);
264 if (err
!= -EPERM
&& err
!= -ENODEV
)
265 nfc_err(&drv_data
->udev
->dev
,
266 "urb %p submission failed (%d)\n", urb
, -err
);
267 kfree(urb
->setup_packet
);
268 usb_unanchor_urb(urb
);
270 usb_mark_last_busy(drv_data
->udev
);
278 static struct nfcmrvl_if_ops usb_ops
= {
279 .nci_open
= nfcmrvl_usb_nci_open
,
280 .nci_close
= nfcmrvl_usb_nci_close
,
281 .nci_send
= nfcmrvl_usb_nci_send
,
284 static void nfcmrvl_waker(struct work_struct
*work
)
286 struct nfcmrvl_usb_drv_data
*drv_data
=
287 container_of(work
, struct nfcmrvl_usb_drv_data
, waker
);
290 err
= usb_autopm_get_interface(drv_data
->intf
);
294 usb_autopm_put_interface(drv_data
->intf
);
297 static int nfcmrvl_probe(struct usb_interface
*intf
,
298 const struct usb_device_id
*id
)
300 struct usb_endpoint_descriptor
*ep_desc
;
301 struct nfcmrvl_usb_drv_data
*drv_data
;
302 struct nfcmrvl_private
*priv
;
304 struct usb_device
*udev
= interface_to_usbdev(intf
);
305 struct nfcmrvl_platform_data config
;
307 /* No configuration for USB */
308 memset(&config
, 0, sizeof(config
));
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(drv_data
, &usb_ops
,
346 &drv_data
->udev
->dev
, &config
);
348 return PTR_ERR(priv
);
350 drv_data
->priv
= priv
;
351 drv_data
->priv
->phy
= NFCMRVL_PHY_USB
;
352 priv
->dev
= &drv_data
->udev
->dev
;
354 usb_set_intfdata(intf
, drv_data
);
359 static void nfcmrvl_disconnect(struct usb_interface
*intf
)
361 struct nfcmrvl_usb_drv_data
*drv_data
= usb_get_intfdata(intf
);
366 nfc_info(&drv_data
->udev
->dev
, "intf %p\n", intf
);
368 nfcmrvl_nci_unregister_dev(drv_data
->priv
);
370 usb_set_intfdata(drv_data
->intf
, NULL
);
374 static int nfcmrvl_suspend(struct usb_interface
*intf
, pm_message_t message
)
376 struct nfcmrvl_usb_drv_data
*drv_data
= usb_get_intfdata(intf
);
378 nfc_info(&drv_data
->udev
->dev
, "intf %p\n", intf
);
380 if (drv_data
->suspend_count
++)
383 spin_lock_irq(&drv_data
->txlock
);
384 if (!(PMSG_IS_AUTO(message
) && drv_data
->tx_in_flight
)) {
385 set_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
386 spin_unlock_irq(&drv_data
->txlock
);
388 spin_unlock_irq(&drv_data
->txlock
);
389 drv_data
->suspend_count
--;
393 nfcmrvl_usb_stop_traffic(drv_data
);
394 usb_kill_anchored_urbs(&drv_data
->tx_anchor
);
399 static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data
*drv_data
)
404 while ((urb
= usb_get_from_anchor(&drv_data
->deferred
))) {
405 err
= usb_submit_urb(urb
, GFP_ATOMIC
);
409 drv_data
->tx_in_flight
++;
411 usb_scuttle_anchored_urbs(&drv_data
->deferred
);
414 static int nfcmrvl_resume(struct usb_interface
*intf
)
416 struct nfcmrvl_usb_drv_data
*drv_data
= usb_get_intfdata(intf
);
419 nfc_info(&drv_data
->udev
->dev
, "intf %p\n", intf
);
421 if (--drv_data
->suspend_count
)
424 if (!test_bit(NFCMRVL_NCI_RUNNING
, &drv_data
->flags
))
427 if (test_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
)) {
428 err
= nfcmrvl_submit_bulk_urb(drv_data
, GFP_NOIO
);
430 clear_bit(NFCMRVL_USB_BULK_RUNNING
, &drv_data
->flags
);
434 nfcmrvl_submit_bulk_urb(drv_data
, GFP_NOIO
);
437 spin_lock_irq(&drv_data
->txlock
);
438 nfcmrvl_play_deferred(drv_data
);
439 clear_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
440 spin_unlock_irq(&drv_data
->txlock
);
445 usb_scuttle_anchored_urbs(&drv_data
->deferred
);
447 spin_lock_irq(&drv_data
->txlock
);
448 clear_bit(NFCMRVL_USB_SUSPENDING
, &drv_data
->flags
);
449 spin_unlock_irq(&drv_data
->txlock
);
455 static struct usb_driver nfcmrvl_usb_driver
= {
457 .probe
= nfcmrvl_probe
,
458 .disconnect
= nfcmrvl_disconnect
,
460 .suspend
= nfcmrvl_suspend
,
461 .resume
= nfcmrvl_resume
,
462 .reset_resume
= nfcmrvl_resume
,
464 .id_table
= nfcmrvl_table
,
465 .supports_autosuspend
= 1,
466 .disable_hub_initiated_lpm
= 1,
469 module_usb_driver(nfcmrvl_usb_driver
);
471 MODULE_AUTHOR("Marvell International Ltd.");
472 MODULE_DESCRIPTION("Marvell NFC-over-USB driver ver " VERSION
);
473 MODULE_VERSION(VERSION
);
474 MODULE_LICENSE("GPL v2");