-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Wesley W. Terpstra
authored and
Greg Kroah-Hartman
committed
Apr 11, 2013
1 parent
0fcb998
commit 1157f69
Showing
3 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* USB Wishbone-Serial adapter driver | ||
* | ||
* Copyright (C) 2013 Wesley W. Terpstra <w.terpstra@gsi.de> | ||
* Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/init.h> | ||
#include <linux/tty.h> | ||
#include <linux/module.h> | ||
#include <linux/usb.h> | ||
#include <linux/usb/serial.h> | ||
#include <linux/uaccess.h> | ||
|
||
#define GSI_VENDOR_OPENCLOSE 0xB0 | ||
|
||
static const struct usb_device_id id_table[] = { | ||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1D50, 0x6062, 0xFF, 0xFF, 0xFF) }, | ||
{ }, | ||
}; | ||
MODULE_DEVICE_TABLE(usb, id_table); | ||
|
||
/* | ||
* Etherbone must be told that a new stream has begun before data arrives. | ||
* This is necessary to restart the negotiation of Wishbone bus parameters. | ||
* Similarly, when the stream ends, Etherbone must be told so that the cycle | ||
* line can be driven low in the case that userspace failed to do so. | ||
*/ | ||
static int usb_gsi_openclose(struct usb_serial_port *port, int value) | ||
{ | ||
struct usb_device *dev = port->serial->dev; | ||
|
||
return usb_control_msg( | ||
dev, | ||
usb_sndctrlpipe(dev, 0), /* Send to EP0OUT */ | ||
GSI_VENDOR_OPENCLOSE, | ||
USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | ||
value, /* wValue = device is open(1) or closed(0) */ | ||
port->serial->interface->cur_altsetting->desc.bInterfaceNumber, | ||
0, 0, /* There is no data stage */ | ||
5000); /* Timeout till operation fails */ | ||
} | ||
|
||
static int wishbone_serial_open(struct tty_struct *tty, | ||
struct usb_serial_port *port) | ||
{ | ||
int retval; | ||
|
||
retval = usb_gsi_openclose(port, 1); | ||
if (retval) { | ||
dev_err(&port->serial->dev->dev, | ||
"Could not mark device as open (%d)\n", | ||
retval); | ||
return retval; | ||
} | ||
|
||
retval = usb_serial_generic_open(tty, port); | ||
if (retval) | ||
usb_gsi_openclose(port, 0); | ||
|
||
return retval; | ||
} | ||
|
||
static void wishbone_serial_close(struct usb_serial_port *port) | ||
{ | ||
usb_serial_generic_close(port); | ||
usb_gsi_openclose(port, 0); | ||
} | ||
|
||
static struct usb_serial_driver wishbone_serial_device = { | ||
.driver = { | ||
.owner = THIS_MODULE, | ||
.name = "wishbone_serial", | ||
}, | ||
.id_table = id_table, | ||
.num_ports = 1, | ||
.open = &wishbone_serial_open, | ||
.close = &wishbone_serial_close, | ||
}; | ||
|
||
static struct usb_serial_driver * const serial_drivers[] = { | ||
&wishbone_serial_device, NULL | ||
}; | ||
|
||
module_usb_serial_driver(serial_drivers, id_table); | ||
|
||
MODULE_AUTHOR("Wesley W. Terpstra <w.terpstra@gsi.de>"); | ||
MODULE_DESCRIPTION("USB Wishbone-Serial adapter"); | ||
MODULE_LICENSE("GPL"); |