Root/drivers/ieee802154/spi_atusb.c

1/*
2 * spi_atusb - SPI host look-alike for ATUSB
3 *
4 * Copyright (c) 2011 Richard Sharpe <realrichardsharpe@gmail.com>
5 * Copyright (c) 2011 Stefan Schmidt <stefan@datenfreihafen.org>
6 * Copyright (c) 2011 Werner Almesberger <werner@almesberger.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2
11 *
12 */
13
14/*
15 * - implement more robust interrupt synchronization
16 * - check URB killing in atusb_disconnect for races
17 * - switch from bulk to interrupt endpoint
18 * - implement buffer read without extra copy
19 * - harmonize indentation style
20 * - mv atusb.c ../ieee802.15.4/spi_atusb.c, or maybe atrf_atusb.c or such
21 * - check module load/unload
22 * - review dev_* severity levels
23 */
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/jiffies.h>
29#include <linux/timer.h>
30#include <linux/interrupt.h>
31#include <linux/usb.h>
32#include <linux/spi/spi.h>
33#include <linux/spi/at86rf230.h>
34
35#include "at86rf230.h"
36
37
38#define SYNC_TIMEOUT_MS 50 /* assume interrupt has been synced after
39                   waiting this long */
40
41#define VENDOR_ID 0x20b7
42#define PRODUCT_ID 0x1540
43
44/* The devices we work with */
45static const struct usb_device_id atusb_device_table[] = {
46    { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
47    { },
48};
49MODULE_DEVICE_TABLE(usb, atusb_device_table);
50
51#define ATUSB_BUILD_SIZE 256
52struct atusb_local {
53    struct usb_device * udev;
54    /* The interface to the RF part info, if applicable */
55    uint8_t ep0_atusb_major;
56    uint8_t ep0_atusb_minor;
57    uint8_t atusb_hw_type;
58    struct spi_master *master;
59    int slave_irq;
60    struct urb *irq_urb;
61    uint8_t irq_buf; /* receive irq serial here*/
62    uint8_t irq_seen; /* last irq serial from bulk */
63    uint8_t irq_sync; /* last irq serial from WRITE2_SYNC */
64    struct tasklet_struct task; /* interrupt delivery tasklet */
65    struct timer_list timer; /* delay, for interrupt synch */
66    struct at86rf230_platform_data platform_data;
67    /* copy platform_data so that we can adapt .reset_data */
68    struct spi_device *spi;
69// unsigned char buffer[3];
70    unsigned char buffer[260]; /* XXL, just in case */
71    struct spi_message *msg;
72};
73
74/* Commands to our device. Make sure this is synced with the firmware */
75enum atspi_requests {
76    ATUSB_ID = 0x00, /* system status/control grp */
77    ATUSB_BUILD,
78    ATUSB_RESET,
79    ATUSB_RF_RESET = 0x10, /* debug/test group */
80    ATUSB_POLL_INT,
81    ATUSB_TEST, /* atusb-sil only */
82    ATUSB_TIMER,
83    ATUSB_GPIO,
84    ATUSB_SLP_TR,
85    ATUSB_GPIO_CLEANUP,
86    ATUSB_REG_WRITE = 0x20, /* transceiver group */
87    ATUSB_REG_READ,
88    ATUSB_BUF_WRITE,
89    ATUSB_BUF_READ,
90    ATUSB_SRAM_WRITE,
91    ATUSB_SRAM_READ,
92    ATUSB_SPI_WRITE = 0x30, /* SPI group */
93    ATUSB_SPI_READ1,
94    ATUSB_SPI_READ2,
95    ATUSB_SPI_WRITE2_SYNC,
96};
97
98/*
99 * Direction bRequest wValue wIndex wLength
100 *
101 * ->host ATUSB_ID - - 3
102 * ->host ATUSB_BUILD - - #bytes
103 * host-> ATUSB_RESET - - 0
104 *
105 * host-> ATUSB_RF_RESET - - 0
106 * ->host ATUSB_POLL_INT - - 1
107 * host-> ATUSB_TEST - - 0
108 * ->host ATUSB_TIMER - - #bytes (6)
109 * ->host ATUSB_GPIO dir+data mask+p# 3
110 * host-> ATUSB_SLP_TR - - 0
111 * host-> ATUSB_GPIO_CLEANUP - - 0
112 *
113 * host-> ATUSB_REG_WRITE value addr 0
114 * ->host ATUSB_REG_READ - addr 1
115 * host-> ATUSB_BUF_WRITE - - #bytes
116 * ->host ATUSB_BUF_READ - - #bytes
117 * host-> ATUSB_SRAM_WRITE - addr #bytes
118 * ->host ATUSB_SRAM_READ - addr #bytes
119 *
120 * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
121 * ->host ATUSB_SPI_READ1 byte0 - #bytes
122 * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes
123 * ->host ATUSB_SPI_WRITE2_SYNC byte0 byte1 0/1
124 */
125
126#define ATUSB_FROM_DEV (USB_TYPE_VENDOR | USB_DIR_IN)
127#define ATUSB_TO_DEV (USB_TYPE_VENDOR | USB_DIR_OUT)
128
129
130/* ----- Control transfers ------------------------------------------------- */
131
132
133static int atusb_async_errchk(struct urb *urb)
134{
135    struct atusb_local *atusb = urb->context;
136    struct spi_message *msg = atusb->msg;
137    struct usb_device *dev = atusb->udev;
138
139    if (!urb->status) {
140        dev_dbg(&dev->dev, "atusb_async_errchk OK len %d\n",
141            urb->actual_length);
142        return 0;
143    }
144    
145    if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
146        urb->status != -ESHUTDOWN)
147        dev_info(&dev->dev, "atusb_async_errchk FAIL error %d\n",
148            urb->status);
149
150    msg->actual_length = 0;
151
152    return urb->status;
153}
154
155static void atusb_async_finish(struct urb *urb)
156{
157    struct atusb_local *atusb = urb->context;
158    struct spi_message *msg = atusb->msg;
159
160    msg->status = urb->status;
161    msg->complete(msg->context);
162
163    kfree(urb->setup_packet);
164    usb_free_urb(urb);
165}
166
167static void atusb_ctrl_cb(struct urb *urb)
168{
169    atusb_async_errchk(urb);
170    atusb_async_finish(urb);
171}
172
173static void atusb_timer(unsigned long data)
174{
175    struct urb *urb = (void *) data;
176
177    dev_warn(&urb->dev->dev, "atusb_timer\n");
178    atusb_async_finish(urb);
179}
180
181static void atusb_ctrl_cb_sync(struct urb *urb)
182{
183    struct atusb_local *atusb = urb->context;
184
185    /* @@@ needs locking/atomic */
186    if (atusb_async_errchk(urb) || atusb->irq_sync == atusb->irq_seen) {
187        atusb_async_finish(urb);
188        return;
189    }
190    
191    BUG_ON(timer_pending(&atusb->timer));
192    atusb->timer.expires = jiffies+msecs_to_jiffies(SYNC_TIMEOUT_MS);
193    atusb->timer.data = (unsigned long) urb;
194    add_timer(&atusb->timer);
195}
196
197static void atusb_read_fb_cb(struct urb *urb)
198{
199    struct atusb_local *atusb = urb->context;
200    struct spi_message *msg = atusb->msg;
201    const struct spi_transfer *xfer;
202    uint8_t *rx;
203
204    if (!atusb_async_errchk(urb)) {
205        BUG_ON(!urb->actual_length);
206
207        xfer = list_first_entry(&msg->transfers, struct spi_transfer,
208            transfer_list);
209        rx = xfer->rx_buf;
210        rx[1] = atusb->buffer[0];
211
212        xfer = list_entry(xfer->transfer_list.next,
213            struct spi_transfer, transfer_list);
214        memcpy(xfer->rx_buf, atusb->buffer+1, urb->actual_length-1);
215    }
216
217    atusb_async_finish(urb);
218}
219
220static int submit_control_msg(struct atusb_local *atusb,
221    __u8 request, __u8 requesttype, __u16 value, __u16 index,
222    void *data, __u16 size, usb_complete_t complete_fn, void *context)
223{
224    struct usb_device *dev = atusb->udev;
225    struct usb_ctrlrequest *req;
226    struct urb *urb;
227    int retval = -ENOMEM;
228
229    req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
230    if (!req)
231        return -ENOMEM;
232
233    req->bRequest = request;
234    req->bRequestType = requesttype;
235    req->wValue = cpu_to_le16(value);
236    req->wIndex = cpu_to_le16(index);
237    req->wLength = cpu_to_le16(size);
238
239    urb = usb_alloc_urb(0, GFP_KERNEL);
240    if (!urb)
241        goto out_nourb;
242
243    usb_fill_control_urb(urb, dev,
244        requesttype == ATUSB_FROM_DEV ?
245          usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0),
246        (unsigned char *) req, data, size, complete_fn, context);
247
248    retval = usb_submit_urb(urb, GFP_KERNEL);
249    if (!retval)
250        return 0;
251    dev_warn(&dev->dev, "failed submitting read urb, error %d",
252        retval);
253    retval = retval == -ENOMEM ? retval : -EIO;
254
255    usb_free_urb(urb);
256out_nourb:
257    kfree(req);
258
259    return retval;
260}
261
262
263/* ----- SPI transfers ----------------------------------------------------- */
264
265
266static int atusb_read1(struct atusb_local *atusb,
267    uint8_t tx, uint8_t *rx, int len)
268{
269    dev_dbg(&atusb->udev->dev, "atusb_read1: tx = 0x%x\n", tx);
270    return submit_control_msg(atusb,
271        ATUSB_SPI_READ1, ATUSB_FROM_DEV, tx, 0,
272        rx, 1, atusb_ctrl_cb, atusb);
273}
274
275static int atusb_read_fb(struct atusb_local *atusb,
276    uint8_t tx, uint8_t *rx0, uint8_t *rx, int len)
277{
278    dev_dbg(&atusb->udev->dev, "atusb_read_fb: tx = 0x%x\n", tx);
279    return submit_control_msg(atusb,
280        ATUSB_SPI_READ1, ATUSB_FROM_DEV, tx, 0,
281        atusb->buffer, len+1, atusb_read_fb_cb, atusb);
282}
283
284static int atusb_write(struct atusb_local *atusb,
285    uint8_t tx0, uint8_t tx1, const uint8_t *tx, int len)
286{
287    dev_dbg(&atusb->udev->dev,
288        "atusb_write: tx0 = 0x%x tx1 = 0x%x\n", tx0, tx1);
289
290    /*
291     * The AT86RF230 driver sometimes requires a transceiver state
292     * transition to be an interrupt barrier. This is the case after
293     * writing FORCE_TX_ON to the TRX_CMD field in the TRX_STATE register.
294     *
295     * Since there is no other means of notification, we just decode the
296     * transfer and do a bit of pattern matching.
297     */
298    if (tx0 == (CMD_REG | CMD_WRITE | RG_TRX_STATE) &&
299        (tx1 & 0x1f) == STATE_FORCE_TX_ON)
300        return submit_control_msg(atusb,
301            ATUSB_SPI_WRITE2_SYNC, ATUSB_FROM_DEV, tx0, tx1,
302             &atusb->irq_sync, 1, atusb_ctrl_cb_sync, atusb);
303    else
304        return submit_control_msg(atusb,
305            ATUSB_SPI_WRITE, ATUSB_TO_DEV, tx0, tx1,
306            (uint8_t *) tx, len, atusb_ctrl_cb, atusb);
307}
308
309static int atusb_transfer(struct spi_device *spi, struct spi_message *msg)
310{
311    struct atusb_local *atusb = spi_master_get_devdata(spi->master);
312    struct spi_transfer *xfer;
313    struct spi_transfer *x[2];
314    int n;
315    const uint8_t *tx;
316    uint8_t *rx;
317    int len;
318    int retval = 0;
319
320    if (unlikely(list_empty(&msg->transfers))) {
321        dev_err(&atusb->udev->dev, "transfer is empty\n");
322        return -EINVAL;
323    }
324
325    atusb->msg = msg;
326
327    /* Classify the request */
328    n = 0;
329    list_for_each_entry(xfer, &msg->transfers, transfer_list) {
330        if (n == ARRAY_SIZE(x)) {
331            dev_err(&atusb->udev->dev, "too many transfers\n");
332            return -EINVAL;
333        }
334        x[n] = xfer;
335        n++;
336    }
337
338    tx = x[0]->tx_buf;
339    rx = x[0]->rx_buf;
340    len = x[0]->len;
341
342    msg->actual_length = len;
343
344    if (!tx || len != 2)
345        goto bad_req;
346    if (n == 1) {
347        if (rx) {
348            dev_dbg(&atusb->udev->dev, "read 1\n");
349            retval = atusb_read1(atusb, tx[0], rx+1, len-1);
350        } else {
351            dev_dbg(&atusb->udev->dev, "write 2\n");
352            /*
353             * Don't take our clock away !! ;-)
354             */
355            if (tx[0] == (CMD_REG | CMD_WRITE | RG_TRX_CTRL_0)) {
356                msg->status = 0;
357                msg->complete(msg->context);
358            } else {
359                retval = atusb_write(atusb,
360                    tx[0], tx[1], NULL, 0);
361            }
362        }
363    } else {
364        if (x[0]->rx_buf) {
365            if (x[1]->tx_buf || !x[1]->rx_buf)
366                goto bad_req;
367            dev_dbg(&atusb->udev->dev, "read 1+\n");
368            retval = atusb_read_fb(atusb, tx[0], rx+1,
369                x[1]->rx_buf, x[1]->len);
370        } else {
371            if (!x[1]->tx_buf ||x[1]->rx_buf)
372                goto bad_req;
373            dev_dbg(&atusb->udev->dev, "write 2+n\n");
374            retval = atusb_write(atusb, tx[0], tx[1],
375                x[1]->tx_buf, x[1]->len);
376        }
377    }
378    return retval;
379
380bad_req:
381    dev_err(&atusb->udev->dev, "unrecognized request:\n");
382    list_for_each_entry(xfer, &msg->transfers, transfer_list)
383        dev_err(&atusb->udev->dev, "%stx %srx len %u\n",
384            xfer->tx_buf ? "" : "!", xfer->rx_buf ? " " : "!",
385            xfer->len);
386    return -EINVAL;
387}
388
389static int atusb_setup(struct spi_device *spi)
390{
391    return 0;
392}
393
394
395/* ----- Interrupt handling ------------------------------------------------ */
396
397
398static void atusb_tasklet(unsigned long data)
399{
400    struct atusb_local *atusb = (void *) data;
401
402    generic_handle_irq(atusb->slave_irq);
403}
404
405static void atusb_irq(struct urb *urb)
406{
407    struct atusb_local *atusb = urb->context;
408
409    dev_dbg(&urb->dev->dev, "atusb_irq (%d), seen %d sync %d\n",
410        urb->status, atusb->irq_buf, atusb->irq_sync);
411    if (!urb->status) {
412        atusb->irq_seen = atusb->irq_buf;
413        if (atusb->irq_sync == atusb->irq_seen &&
414            try_to_del_timer_sync(&atusb->timer) == 1)
415            atusb_async_finish((struct urb *) atusb->timer.data);
416    }
417    usb_free_urb(urb);
418    atusb->irq_urb = NULL;
419    tasklet_schedule(&atusb->task);
420}
421
422static int atusb_arm_interrupt(struct atusb_local *atusb)
423{
424    struct usb_device *dev = atusb->udev;
425    struct urb *urb;
426    int retval = -ENOMEM;
427
428    BUG_ON(atusb->irq_urb);
429
430    dev_vdbg(&dev->dev, "atusb_arm_interrupt\n");
431    urb = usb_alloc_urb(0, GFP_KERNEL);
432    if (!urb) {
433        dev_err(&dev->dev,
434            "atusb_arm_interrupt: usb_alloc_urb failed\n");
435        return -ENOMEM;
436    }
437
438    usb_fill_bulk_urb(urb, dev, usb_rcvbulkpipe(dev, 1),
439        &atusb->irq_buf, 1, atusb_irq, atusb);
440    atusb->irq_urb = urb;
441    retval = usb_submit_urb(urb, GFP_KERNEL);
442    if (!retval)
443        return 0;
444
445    dev_err(&dev->dev, "failed submitting bulk urb, error %d\n", retval);
446    retval = retval == -ENOMEM ? retval : -EIO;
447
448    usb_free_urb(urb);
449
450    return retval;
451}
452
453static void atusb_irq_mask(struct irq_data *data)
454{
455    struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
456
457    dev_vdbg(&atusb->udev->dev, "atusb_irq_mask\n");
458    tasklet_disable_nosync(&atusb->task);
459}
460
461static void atusb_irq_unmask(struct irq_data *data)
462{
463    struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
464
465    dev_vdbg(&atusb->udev->dev, "atusb_irq_unmask\n");
466    tasklet_enable(&atusb->task);
467}
468
469static void atusb_irq_ack(struct irq_data *data)
470{
471    struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
472
473    dev_vdbg(&atusb->udev->dev, "atusb_irq_ack\n");
474    atusb_arm_interrupt(atusb);
475}
476
477static struct irq_chip atusb_irq_chip = {
478    .name = "atusb-slave",
479    .irq_mask = atusb_irq_mask,
480    .irq_unmask = atusb_irq_unmask,
481    .irq_ack = atusb_irq_ack,
482};
483
484
485/* ----- Transceiver reset ------------------------------------------------- */
486
487
488static void atusb_reset(void *reset_data)
489{
490    int retval;
491    struct atusb_local *atusb = reset_data;
492
493    retval = usb_control_msg(atusb->udev,
494        usb_rcvctrlpipe(atusb->udev, 0),
495        ATUSB_RF_RESET, ATUSB_TO_DEV, 0, 0,
496        NULL, 0, 1000);
497    if (retval < 0) {
498        dev_err(&atusb->udev->dev,
499            "%s: error doing reset retval = %d\n",
500            __func__, retval);
501    }
502}
503
504
505/* ----- Firmware version information -------------------------------------- */
506
507
508static int atusb_get_and_show_revision(struct atusb_local *atusb)
509{
510    struct usb_device *dev = atusb->udev;
511    int retval;
512
513    /* Get a couple of the ATMega Firmware values */
514    retval = usb_control_msg(dev,
515        usb_rcvctrlpipe(dev, 0),
516        ATUSB_ID, ATUSB_FROM_DEV, 0, 0,
517        atusb->buffer, 3, 1000);
518    if (retval < 0) {
519        dev_info(&dev->dev,
520            "failed submitting urb for ATUSB_ID, error %d\n", retval);
521        return retval == -ENOMEM ? retval : -EIO;
522    }
523
524    atusb->ep0_atusb_major = atusb->buffer[0];
525    atusb->ep0_atusb_minor = atusb->buffer[1];
526    atusb->atusb_hw_type = atusb->buffer[2];
527    dev_info(&dev->dev,
528        "Firmware: major: %u, minor: %u, hardware type: %u\n",
529        atusb->ep0_atusb_major, atusb->ep0_atusb_minor,
530        atusb->atusb_hw_type);
531
532    return 0;
533}
534
535static int atusb_get_and_show_build(struct atusb_local *atusb)
536{
537    struct usb_device *dev = atusb->udev;
538    char build[ATUSB_BUILD_SIZE+1];
539    int retval;
540
541    retval = usb_control_msg(dev,
542        usb_rcvctrlpipe(atusb->udev, 0),
543        ATUSB_BUILD, ATUSB_FROM_DEV, 0, 0,
544        build, ATUSB_BUILD_SIZE, 1000);
545    if (retval < 0) {
546        dev_err(&dev->dev,
547            "failed submitting urb for ATUSB_BUILD, error %d\n",
548            retval);
549        return retval == -ENOMEM ? retval : -EIO;
550    }
551
552    build[retval] = 0;
553    dev_info(&dev->dev, "Firmware: build %s\n", build);
554
555    return 0;
556}
557
558
559/* ----- Setup ------------------------------------------------------------- */
560
561
562struct at86rf230_platform_data at86rf230_platform_data = {
563    .rstn = -1,
564    .slp_tr = -1,
565    .dig2 = -1,
566    .reset = atusb_reset,
567    /* set .reset_data later */
568};
569
570static int atusb_probe(struct usb_interface *interface,
571            const struct usb_device_id *id)
572{
573    struct spi_board_info board_info = {
574        .modalias = "at86rf230",
575        /* set .irq later */
576        .chip_select = 0,
577        .bus_num = -1,
578        .max_speed_hz = 8 * 1000 * 1000,
579    };
580
581    struct usb_device *udev = interface_to_usbdev(interface);
582    struct atusb_local *atusb = NULL;
583    struct spi_master *master;
584    int retval;
585
586    /*
587     * Ignore all interfaces used for DFU, i.e., everything while in the
588     * boot loader, and interface #1 when in the application.
589     */
590    if (interface->cur_altsetting->desc.bInterfaceClass !=
591        USB_CLASS_VENDOR_SPEC) {
592        dev_dbg(&udev->dev,
593            "Ignoring interface with class 0x%02x\n",
594            interface->cur_altsetting->desc.bInterfaceClass);
595        return -ENODEV;
596    }
597
598    master = spi_alloc_master(&udev->dev, sizeof(*atusb));
599    if (!master)
600        return -ENOMEM;
601
602    atusb = spi_master_get_devdata(master);
603
604    atusb->udev = usb_get_dev(udev);
605    usb_set_intfdata(interface, atusb);
606
607    atusb->master = spi_master_get(master);
608
609    master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
610    master->bus_num = -1;
611    master->num_chipselect = 1;
612    master->setup = atusb_setup;
613    master->transfer = atusb_transfer;
614
615    atusb->slave_irq = irq_alloc_desc(numa_node_id());
616    if (atusb->slave_irq < 0) {
617        dev_err(&udev->dev, "can't allocate slave irq\n");
618        retval = -ENXIO;
619        goto err_free;
620    }
621
622    set_irq_chip_data(atusb->slave_irq, atusb);
623    set_irq_chip_and_handler(atusb->slave_irq, &atusb_irq_chip,
624        handle_level_irq);
625
626    /* FIXME prepare USB IRQ */
627
628    retval = spi_register_master(master);
629    if (retval < 0) {
630        dev_err(&udev->dev, "can't register spi master\n");
631        goto err_slave_irq;
632    }
633
634    atusb->platform_data = at86rf230_platform_data;
635    atusb->platform_data.reset_data = atusb;
636    board_info.platform_data = &atusb->platform_data;
637    board_info.irq = atusb->slave_irq;
638
639    init_timer(&atusb->timer);
640    atusb->timer.function = atusb_timer;
641
642    tasklet_init(&atusb->task, atusb_tasklet, (unsigned long) atusb);
643    tasklet_disable(&atusb->task);
644    atusb_arm_interrupt(atusb);
645
646    if (atusb_get_and_show_revision(atusb) < 0)
647        goto err_master;
648    if (atusb_get_and_show_build(atusb) < 0)
649        goto err_master;
650
651    atusb->spi = spi_new_device(master, &board_info);
652    if (!atusb->spi) {
653        dev_err(&udev->dev, "can't create new device for %s\n",
654            board_info.modalias);
655        goto err_master;
656    }
657
658    dev_info(&atusb->spi->dev,
659        "ATUSB ready for mischief (IRQ %d)\n", board_info.irq);
660
661    return 0;
662
663err_master:
664    /*
665     * If we come here from a partially successful driver initialization,
666     * we don't really know how much it has done. In particular, it may
667     * have triggered an interrupt and thus removed the interrupt URB and
668     * maybe scheduled the tasklet.
669     */
670    tasklet_disable(&atusb->task);
671    if (atusb->irq_urb)
672        usb_kill_urb(atusb->irq_urb);
673    spi_master_put(atusb->master);
674err_slave_irq:
675    set_irq_chained_handler(atusb->slave_irq, NULL);
676    set_irq_chip_data(atusb->slave_irq, NULL);
677    irq_free_desc(atusb->slave_irq);
678err_free:
679    return retval;
680}
681
682static void atusb_disconnect(struct usb_interface *interface)
683{
684    struct atusb_local *atusb = usb_get_intfdata(interface);
685    struct spi_master *master = atusb->master;
686
687    tasklet_disable(&atusb->task);
688    /* @@@ this needs some extra protecion - wa */
689    if (atusb->irq_urb)
690        usb_kill_urb(atusb->irq_urb);
691
692    BUG_ON(timer_pending(&atusb->timer));
693
694    usb_set_intfdata(interface, NULL);
695    usb_put_dev(atusb->udev);
696
697    spi_dev_put(atusb->spi);
698
699    spi_unregister_master(master);
700
701    set_irq_chained_handler(atusb->slave_irq, NULL);
702    set_irq_chip_data(atusb->slave_irq, NULL);
703    irq_free_desc(atusb->slave_irq);
704
705    spi_master_put(master);
706}
707
708void atusb_release(struct device *dev)
709{
710    return;
711}
712
713static struct usb_driver atusb_driver = {
714    .name = "atusb_ben-wpan",
715    .probe = atusb_probe,
716    .disconnect = atusb_disconnect,
717    .id_table = atusb_device_table,
718};
719
720static struct platform_device atusb_device = {
721    .name = "spi_atusb",
722    .id = -1,
723    .dev.release = atusb_release,
724};
725
726static int __init atusb_init(void)
727{
728    int retval;
729
730    retval = platform_device_register(&atusb_device);
731    if (retval)
732        return retval;
733
734    return usb_register(&atusb_driver);
735}
736
737static void __exit atusb_exit(void)
738{
739    usb_deregister(&atusb_driver);
740    platform_device_unregister(&atusb_device);
741}
742
743module_init (atusb_init);
744module_exit (atusb_exit);
745
746MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>");
747MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>");
748MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
749MODULE_DESCRIPTION("ATUSB ben-wpan Driver");
750MODULE_LICENSE("GPL");
751

Archive Download this file



interactive