linux/drivers/usb/serial/ch341.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2007, Frank A Kingswood <[email protected]>
 * Copyright 2007, Werner Cornelius <[email protected]>
 * Copyright 2009, Boris Hajduk <[email protected]>
 *
 * ch341.c implements a serial port driver for the Winchiphead CH341.
 *
 * The CH341 device can be used to implement an RS232 asynchronous
 * serial port, an IEEE-1284 parallel printer port or a memory-like
 * interface. In all cases the CH341 supports an I2C interface as well.
 * This driver only supports the asynchronous serial interface.
 */

#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/serial.h>
#include <asm/unaligned.h>

#define DEFAULT_BAUD_RATE
#define DEFAULT_TIMEOUT

/* flags for IO-Bits */
#define CH341_BIT_RTS
#define CH341_BIT_DTR

/******************************/
/* interrupt pipe definitions */
/******************************/
/* always 4 interrupt bytes */
/* first irq byte normally 0x08 */
/* second irq byte base 0x7d + below */
/* third irq byte base 0x94 + below */
/* fourth irq byte normally 0xee */

/* second interrupt byte */
#define CH341_MULT_STAT

/* status returned in third interrupt answer byte, inverted in data
   from irq */
#define CH341_BIT_CTS
#define CH341_BIT_DSR
#define CH341_BIT_RI
#define CH341_BIT_DCD
#define CH341_BITS_MODEM_STAT

/* Break support - the information used to implement this was gleaned from
 * the Net/FreeBSD uchcom.c driver by Takanori Watanabe.  Domo arigato.
 */

#define CH341_REQ_READ_VERSION
#define CH341_REQ_WRITE_REG
#define CH341_REQ_READ_REG
#define CH341_REQ_SERIAL_INIT
#define CH341_REQ_MODEM_CTRL

#define CH341_REG_BREAK
#define CH341_REG_PRESCALER
#define CH341_REG_DIVISOR
#define CH341_REG_LCR
#define CH341_REG_LCR2

#define CH341_NBREAK_BITS

#define CH341_LCR_ENABLE_RX
#define CH341_LCR_ENABLE_TX
#define CH341_LCR_MARK_SPACE
#define CH341_LCR_PAR_EVEN
#define CH341_LCR_ENABLE_PAR
#define CH341_LCR_STOP_BITS_2
#define CH341_LCR_CS8
#define CH341_LCR_CS7
#define CH341_LCR_CS6
#define CH341_LCR_CS5

#define CH341_QUIRK_LIMITED_PRESCALER
#define CH341_QUIRK_SIMULATE_BREAK

static const struct usb_device_id id_table[] =;
MODULE_DEVICE_TABLE(usb, id_table);

struct ch341_private {};

static void ch341_set_termios(struct tty_struct *tty,
			      struct usb_serial_port *port,
			      const struct ktermios *old_termios);

static int ch341_control_out(struct usb_device *dev, u8 request,
			     u16 value, u16 index)
{}

static int ch341_control_in(struct usb_device *dev,
			    u8 request, u16 value, u16 index,
			    char *buf, unsigned bufsize)
{}

#define CH341_CLKRATE
#define CH341_CLK_DIV(ps, fact)
#define CH341_MIN_RATE(ps)

static const speed_t ch341_min_rates[] =;

/* Supported range is 46 to 3000000 bps. */
#define CH341_MIN_BPS
#define CH341_MAX_BPS

/*
 * The device line speed is given by the following equation:
 *
 *	baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where
 *
 *		0 <= ps <= 3,
 *		0 <= fact <= 1,
 *		2 <= div <= 256 if fact = 0, or
 *		9 <= div <= 256 if fact = 1
 */
static int ch341_get_divisor(struct ch341_private *priv, speed_t speed)
{}

static int ch341_set_baudrate_lcr(struct usb_device *dev,
				  struct ch341_private *priv,
				  speed_t baud_rate, u8 lcr)
{}

static int ch341_set_handshake(struct usb_device *dev, u8 control)
{}

static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
{}

/* -------------------------------------------------------------------------- */

static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
{}

static int ch341_detect_quirks(struct usb_serial_port *port)
{}

static int ch341_port_probe(struct usb_serial_port *port)
{}

static void ch341_port_remove(struct usb_serial_port *port)
{}

static int ch341_carrier_raised(struct usb_serial_port *port)
{}

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

static void ch341_close(struct usb_serial_port *port)
{}


/* open this device, set default parameters */
static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
{}

/* Old_termios contains the original termios settings and
 * tty->termios contains the new setting to be used.
 */
static void ch341_set_termios(struct tty_struct *tty,
			      struct usb_serial_port *port,
			      const struct ktermios *old_termios)
{}

/*
 * A subset of all CH34x devices don't support a real break condition and
 * reading CH341_REG_BREAK fails (see also ch341_detect_quirks). This function
 * simulates a break condition by lowering the baud rate to the minimum
 * supported by the hardware upon enabling the break condition and sending
 * a NUL byte.
 *
 * Incoming data is corrupted while the break condition is being simulated.
 *
 * Normally the duration of the break condition can be controlled individually
 * by userspace using TIOCSBRK and TIOCCBRK or by passing an argument to
 * TCSBRKP. Due to how the simulation is implemented the duration can't be
 * controlled. The duration is always about (1s / 46bd * 9bit) = 196ms.
 */
static int ch341_simulate_break(struct tty_struct *tty, int break_state)
{}

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

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

static void ch341_update_status(struct usb_serial_port *port,
					unsigned char *data, size_t len)
{}

static void ch341_read_int_callback(struct urb *urb)
{}

static int ch341_tiocmget(struct tty_struct *tty)
{}

static int ch341_reset_resume(struct usb_serial *serial)
{}

static struct usb_serial_driver ch341_device =;

static struct usb_serial_driver * const serial_drivers[] =;

module_usb_serial_driver();

MODULE_LICENSE();