diff options
author | Wesley W. Terpstra <w.terpstra@gsi.de> | 2013-04-11 09:08:20 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-11 11:41:56 -0400 |
commit | 1157f69bee295987952bf0cbbcbc419d497eb51c (patch) | |
tree | 4a1f90df57efc9016314204102efb54d789ff2de | |
parent | 0fcb99898633e5def627833613cf262fe7f30ac4 (diff) |
usb-serial: add support for USB Wishbone-serial adapters
Wishbone is an open hardware SoC bus commonly used in FPGA
designs. Bus access can be serialized using the Etherbone
protocol <http://www.ohwr.org/projects/etherbone-core>.
This driver is intended to be used with devices which attach
their internal Wishbone bus to a USB serial interface using
the Etherbone protocol. A userspace library is required to
speak the protocol made available by this driver as ttyUSBx.
Signed-off-by: Wesley W. Terpstra <w.terpstra@gsi.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/serial/Kconfig | 17 | ||||
-rw-r--r-- | drivers/usb/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/serial/wishbone-serial.c | 95 |
3 files changed, 113 insertions, 0 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index bf3733629b09..1d55762afbb1 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -667,6 +667,23 @@ config USB_SERIAL_ZIO | |||
667 | To compile this driver as a module, choose M here: the | 667 | To compile this driver as a module, choose M here: the |
668 | module will be called zio. | 668 | module will be called zio. |
669 | 669 | ||
670 | config USB_SERIAL_WISHBONE | ||
671 | tristate "USB-Wishbone adapter interface driver" | ||
672 | help | ||
673 | Say Y here if you want to use a USB attached Wishbone bus. | ||
674 | |||
675 | Wishbone is an open hardware SoC bus commonly used in FPGA | ||
676 | designs. Bus access can be serialized using the Etherbone | ||
677 | protocol <http://www.ohwr.org/projects/etherbone-core>. | ||
678 | |||
679 | This driver is intended to be used with devices which attach | ||
680 | their internal Wishbone bus to a USB serial interface using | ||
681 | the Etherbone protocol. A userspace library is required to | ||
682 | speak the protocol made available by this driver as ttyUSBx. | ||
683 | |||
684 | To compile this driver as a module, choose M here: the | ||
685 | module will be called wishbone-serial. | ||
686 | |||
670 | config USB_SERIAL_ZTE | 687 | config USB_SERIAL_ZTE |
671 | tristate "ZTE USB serial driver" | 688 | tristate "ZTE USB serial driver" |
672 | help | 689 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index eaf5ca14dfeb..cec63fa19104 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -58,6 +58,7 @@ obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o | |||
58 | obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o | 58 | obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o |
59 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | 59 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o |
60 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o | 60 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o |
61 | obj-$(CONFIG_USB_SERIAL_WISHBONE) += wishbone-serial.o | ||
61 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o | 62 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o |
62 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o | 63 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o |
63 | obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o | 64 | obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o |
diff --git a/drivers/usb/serial/wishbone-serial.c b/drivers/usb/serial/wishbone-serial.c new file mode 100644 index 000000000000..481ec669bf7c --- /dev/null +++ b/drivers/usb/serial/wishbone-serial.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * USB Wishbone-Serial adapter driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Wesley W. Terpstra <w.terpstra@gsi.de> | ||
5 | * Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/tty.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/usb.h> | ||
18 | #include <linux/usb/serial.h> | ||
19 | #include <linux/uaccess.h> | ||
20 | |||
21 | #define GSI_VENDOR_OPENCLOSE 0xB0 | ||
22 | |||
23 | static const struct usb_device_id id_table[] = { | ||
24 | { USB_DEVICE_AND_INTERFACE_INFO(0x1D50, 0x6062, 0xFF, 0xFF, 0xFF) }, | ||
25 | { }, | ||
26 | }; | ||
27 | MODULE_DEVICE_TABLE(usb, id_table); | ||
28 | |||
29 | /* | ||
30 | * Etherbone must be told that a new stream has begun before data arrives. | ||
31 | * This is necessary to restart the negotiation of Wishbone bus parameters. | ||
32 | * Similarly, when the stream ends, Etherbone must be told so that the cycle | ||
33 | * line can be driven low in the case that userspace failed to do so. | ||
34 | */ | ||
35 | static int usb_gsi_openclose(struct usb_serial_port *port, int value) | ||
36 | { | ||
37 | struct usb_device *dev = port->serial->dev; | ||
38 | |||
39 | return usb_control_msg( | ||
40 | dev, | ||
41 | usb_sndctrlpipe(dev, 0), /* Send to EP0OUT */ | ||
42 | GSI_VENDOR_OPENCLOSE, | ||
43 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | ||
44 | value, /* wValue = device is open(1) or closed(0) */ | ||
45 | port->serial->interface->cur_altsetting->desc.bInterfaceNumber, | ||
46 | 0, 0, /* There is no data stage */ | ||
47 | 5000); /* Timeout till operation fails */ | ||
48 | } | ||
49 | |||
50 | static int wishbone_serial_open(struct tty_struct *tty, | ||
51 | struct usb_serial_port *port) | ||
52 | { | ||
53 | int retval; | ||
54 | |||
55 | retval = usb_gsi_openclose(port, 1); | ||
56 | if (retval) { | ||
57 | dev_err(&port->serial->dev->dev, | ||
58 | "Could not mark device as open (%d)\n", | ||
59 | retval); | ||
60 | return retval; | ||
61 | } | ||
62 | |||
63 | retval = usb_serial_generic_open(tty, port); | ||
64 | if (retval) | ||
65 | usb_gsi_openclose(port, 0); | ||
66 | |||
67 | return retval; | ||
68 | } | ||
69 | |||
70 | static void wishbone_serial_close(struct usb_serial_port *port) | ||
71 | { | ||
72 | usb_serial_generic_close(port); | ||
73 | usb_gsi_openclose(port, 0); | ||
74 | } | ||
75 | |||
76 | static struct usb_serial_driver wishbone_serial_device = { | ||
77 | .driver = { | ||
78 | .owner = THIS_MODULE, | ||
79 | .name = "wishbone_serial", | ||
80 | }, | ||
81 | .id_table = id_table, | ||
82 | .num_ports = 1, | ||
83 | .open = &wishbone_serial_open, | ||
84 | .close = &wishbone_serial_close, | ||
85 | }; | ||
86 | |||
87 | static struct usb_serial_driver * const serial_drivers[] = { | ||
88 | &wishbone_serial_device, NULL | ||
89 | }; | ||
90 | |||
91 | module_usb_serial_driver(serial_drivers, id_table); | ||
92 | |||
93 | MODULE_AUTHOR("Wesley W. Terpstra <w.terpstra@gsi.de>"); | ||
94 | MODULE_DESCRIPTION("USB Wishbone-Serial adapter"); | ||
95 | MODULE_LICENSE("GPL"); | ||