2017-11-03 13:28:30 +03:00
// SPDX-License-Identifier: GPL-2.0+
2013-04-11 17:08:20 +04:00
/*
* 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
*/
# include <linux/kernel.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 ,
2013-04-11 19:45:34 +04:00
NULL , 0 , /* There is no data stage */
2013-04-11 17:08:20 +04:00
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 " ) ;