linux/drivers/usb/serial/ftdi_sio.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * USB FTDI SIO driver
 *
 *	Copyright (C) 2009 - 2013
 *	    Johan Hovold ([email protected])
 *	Copyright (C) 1999 - 2001
 *	    Greg Kroah-Hartman ([email protected])
 *          Bill Ryder ([email protected])
 *	Copyright (C) 2002
 *	    Kuba Ober ([email protected])
 *
 * See Documentation/usb/usb-serial.rst for more information on using this
 * driver
 *
 * See http://ftdi-usb-sio.sourceforge.net for up to date testing info
 *	and extra documentation
 *
 * Change entries from 2004 and earlier can be found in versions of this
 * file in kernel versions prior to the 2.6.24 release.
 *
 */

/* Bill Ryder - [email protected] - wrote the FTDI_SIO implementation */
/* Thanx to FTDI for so kindly providing details of the protocol required */
/*   to talk to the device */
/* Thanx to gkh and the rest of the usb dev group for all code I have
   assimilated :-) */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/serial.h>
#include <linux/gpio/driver.h>
#include <linux/usb/serial.h>
#include "ftdi_sio.h"
#include "ftdi_sio_ids.h"

#define DRIVER_AUTHOR
#define DRIVER_DESC

enum ftdi_chip_type {};

struct ftdi_private {};

struct ftdi_quirk {};

static int   ftdi_jtag_probe(struct usb_serial *serial);
static int   ftdi_NDI_device_setup(struct usb_serial *serial);
static int   ftdi_stmclite_probe(struct usb_serial *serial);
static int   ftdi_8u2232c_probe(struct usb_serial *serial);
static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);

static const struct ftdi_quirk ftdi_jtag_quirk =;

static const struct ftdi_quirk ftdi_NDI_device_quirk =;

static const struct ftdi_quirk ftdi_USB_UIRT_quirk =;

static const struct ftdi_quirk ftdi_HE_TIRA1_quirk =;

static const struct ftdi_quirk ftdi_stmclite_quirk =;

static const struct ftdi_quirk ftdi_8u2232c_quirk =;

/*
 * The 8U232AM has the same API as the sio except for:
 * - it can support MUCH higher baudrates; up to:
 *   o 921600 for RS232 and 2000000 for RS422/485 at 48MHz
 *   o 230400 at 12MHz
 *   so .. 8U232AM's baudrate setting codes are different
 * - it has a two byte status code.
 * - it returns characters every 16ms (the FTDI does it every 40ms)
 *
 * the bcdDevice value is used to differentiate FT232BM and FT245BM from
 * the earlier FT8U232AM and FT8U232BM.  For now, include all known VID/PID
 * combinations in both tables.
 * FIXME: perhaps bcdDevice can also identify 12MHz FT8U232AM devices,
 * but I don't know if those ever went into mass production. [Ian Abbott]
 */



/*
 * Device ID not listed? Test it using
 * /sys/bus/usb-serial/drivers/ftdi_sio/new_id and send a patch or report.
 */
static const struct usb_device_id id_table_combined[] =;

MODULE_DEVICE_TABLE(usb, id_table_combined);

static const char *ftdi_chip_name[] =;


/* Used for TIOCMIWAIT */
#define FTDI_STATUS_B0_MASK
#define FTDI_STATUS_B1_MASK
/* End TIOCMIWAIT */

static void ftdi_set_termios(struct tty_struct *tty,
			     struct usb_serial_port *port,
			     const struct ktermios *old_termios);
static int ftdi_get_modem_status(struct usb_serial_port *port,
						unsigned char status[2]);

#define WDR_TIMEOUT
#define WDR_SHORT_TIMEOUT

/*
 * ***************************************************************************
 * Utility functions
 * ***************************************************************************
 */

static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base)
{}

static unsigned short int ftdi_232am_baud_to_divisor(int baud)
{}

static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base)
{}

static u32 ftdi_232bm_baud_to_divisor(int baud)
{}

static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base)
{}

static u32 ftdi_2232h_baud_to_divisor(int baud)
{}

#define set_mctrl(port, set)
#define clear_mctrl(port, clear)

static int update_mctrl(struct usb_serial_port *port, unsigned int set,
							unsigned int clear)
{}


static u32 get_ftdi_divisor(struct tty_struct *tty,
						struct usb_serial_port *port)
{}

static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
{}

static int write_latency_timer(struct usb_serial_port *port)
{}

static int _read_latency_timer(struct usb_serial_port *port)
{}

static int read_latency_timer(struct usb_serial_port *port)
{}

static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss)
{}

static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)
{}

static int get_lsr_info(struct usb_serial_port *port,
			unsigned int __user *retinfo)
{}

static int ftdi_determine_type(struct usb_serial_port *port)
{}


/*
 * Determine the maximum packet size for the device. This depends on the chip
 * type and the USB host capabilities. The value should be obtained from the
 * device descriptor as the chip will use the appropriate values for the host.
 */
static void ftdi_set_max_packet_size(struct usb_serial_port *port)
{}


/*
 * ***************************************************************************
 * Sysfs Attribute
 * ***************************************************************************
 */

static ssize_t latency_timer_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{}

/* Write a new value of the latency timer, in units of milliseconds. */
static ssize_t latency_timer_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *valbuf, size_t count)
{}
static DEVICE_ATTR_RW(latency_timer);

/* Write an event character directly to the FTDI register.  The ASCII
   value is in the low 8 bits, with the enable bit in the 9th bit. */
static ssize_t event_char_store(struct device *dev,
	struct device_attribute *attr, const char *valbuf, size_t count)
{}
static DEVICE_ATTR_WO(event_char);

static struct attribute *ftdi_attrs[] =;

static umode_t ftdi_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
{}

static const struct attribute_group ftdi_group =;

static const struct attribute_group *ftdi_groups[] =;

#ifdef CONFIG_GPIOLIB

static int ftdi_set_bitmode(struct usb_serial_port *port, u8 mode)
{}

static int ftdi_set_cbus_pins(struct usb_serial_port *port)
{}

static int ftdi_exit_cbus_mode(struct usb_serial_port *port)
{}

static int ftdi_gpio_request(struct gpio_chip *gc, unsigned int offset)
{}

static int ftdi_read_cbus_pins(struct usb_serial_port *port)
{}

static int ftdi_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{}

static void ftdi_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value)
{}

static int ftdi_gpio_get_multiple(struct gpio_chip *gc, unsigned long *mask,
					unsigned long *bits)
{}

static void ftdi_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
					unsigned long *bits)
{}

static int ftdi_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio)
{}

static int ftdi_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)
{}

static int ftdi_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio,
					int value)
{}

static int ftdi_gpio_init_valid_mask(struct gpio_chip *gc,
				     unsigned long *valid_mask,
				     unsigned int ngpios)
{}

static int ftdi_read_eeprom(struct usb_serial *serial, void *dst, u16 addr,
				u16 nbytes)
{}

static int ftdi_gpio_init_ft232h(struct usb_serial_port *port)
{}

static int ftdi_gpio_init_ft232r(struct usb_serial_port *port)
{}

static int ftdi_gpio_init_ftx(struct usb_serial_port *port)
{}

static int ftdi_gpio_init(struct usb_serial_port *port)
{}

static void ftdi_gpio_remove(struct usb_serial_port *port)
{}

#else

static int ftdi_gpio_init(struct usb_serial_port *port)
{
	return 0;
}

static void ftdi_gpio_remove(struct usb_serial_port *port) { }

#endif	/* CONFIG_GPIOLIB */

/*
 * ***************************************************************************
 * FTDI driver specific functions
 * ***************************************************************************
 */

static int ftdi_probe(struct usb_serial *serial, const struct usb_device_id *id)
{}

static int ftdi_port_probe(struct usb_serial_port *port)
{}

/* Setup for the USB-UIRT device, which requires hardwired
 * baudrate (38400 gets mapped to 312500) */
/* Called from usbserial:serial_probe */
static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
{}

/* Setup for the HE-TIRA1 device, which requires hardwired
 * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */

static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
{}

/*
 * Module parameter to control latency timer for NDI FTDI-based USB devices.
 * If this value is not set in /etc/modprobe.d/ its value will be set
 * to 1ms.
 */
static int ndi_latency_timer =;

/* Setup for the NDI FTDI-based USB devices, which requires hardwired
 * baudrate (19200 gets mapped to 1200000).
 *
 * Called from usbserial:serial_probe.
 */
static int ftdi_NDI_device_setup(struct usb_serial *serial)
{}

/*
 * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko
 * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from
 * userspace using openocd.
 */
static int ftdi_jtag_probe(struct usb_serial *serial)
{}

static int ftdi_8u2232c_probe(struct usb_serial *serial)
{}

/*
 * First two ports on JTAG adaptors using an FT4232 such as STMicroelectronics's
 * ST Micro Connect Lite are reserved for JTAG or other non-UART interfaces and
 * can be accessed from userspace.
 * The next two ports are enabled as UARTs by default, where port 2 is
 * a conventional RS-232 UART.
 */
static int ftdi_stmclite_probe(struct usb_serial *serial)
{}

static void ftdi_port_remove(struct usb_serial_port *port)
{}

static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
{}

static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
{}

/* The SIO requires the first byte to have:
 *  B0 1
 *  B1 0
 *  B2..7 length of message excluding byte 0
 *
 * The new devices do not require this byte
 */
static int ftdi_prepare_write_buffer(struct usb_serial_port *port,
						void *dest, size_t size)
{}

#define FTDI_RS_ERR_MASK

static int ftdi_process_packet(struct usb_serial_port *port,
		struct ftdi_private *priv, unsigned char *buf, int len)
{}

static void ftdi_process_read_urb(struct urb *urb)
{}

static int ftdi_break_ctl(struct tty_struct *tty, int break_state)
{}

static bool ftdi_tx_empty(struct usb_serial_port *port)
{}

/* old_termios contains the original termios settings and tty->termios contains
 * the new setting to be used
 * WARNING: set_termios calls this with old_termios in kernel space
 */
static void ftdi_set_termios(struct tty_struct *tty,
		             struct usb_serial_port *port,
		             const struct ktermios *old_termios)
{}

/*
 * Get modem-control status.
 *
 * Returns the number of status bytes retrieved (device dependant), or
 * negative error code.
 */
static int ftdi_get_modem_status(struct usb_serial_port *port,
						unsigned char status[2])
{}

static int ftdi_tiocmget(struct tty_struct *tty)
{}

static int ftdi_tiocmset(struct tty_struct *tty,
			unsigned int set, unsigned int clear)
{}

static int ftdi_ioctl(struct tty_struct *tty,
					unsigned int cmd, unsigned long arg)
{}

static struct usb_serial_driver ftdi_device =;

static struct usb_serial_driver * const serial_drivers[] =;
module_usb_serial_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

module_param(ndi_latency_timer, int, 0644);
MODULE_PARM_DESC();