// SPDX-License-Identifier: GPL-2.0+ /* * Clean ups from Moschip version and a few ioctl implementations by: * Paul B Schroeder <pschroeder "at" uplogix "dot" com> * * Originally based on drivers/usb/serial/io_edgeport.c which is: * Copyright (C) 2000 Inside Out Networks, All rights reserved. * Copyright (C) 2001-2002 Greg Kroah-Hartman <[email protected]> * */ #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/serial.h> #include <linux/usb.h> #include <linux/usb/serial.h> #include <linux/uaccess.h> #define DRIVER_DESC … /* * 16C50 UART register defines */ #define LCR_BITS_5 … #define LCR_BITS_6 … #define LCR_BITS_7 … #define LCR_BITS_8 … #define LCR_BITS_MASK … #define LCR_STOP_1 … #define LCR_STOP_1_5 … #define LCR_STOP_2 … #define LCR_STOP_MASK … #define LCR_PAR_NONE … #define LCR_PAR_ODD … #define LCR_PAR_EVEN … #define LCR_PAR_MARK … #define LCR_PAR_SPACE … #define LCR_PAR_MASK … #define LCR_SET_BREAK … #define LCR_DL_ENABLE … #define MCR_DTR … #define MCR_RTS … #define MCR_OUT1 … #define MCR_MASTER_IE … #define MCR_LOOPBACK … #define MCR_XON_ANY … #define MOS7840_MSR_CTS … #define MOS7840_MSR_DSR … #define MOS7840_MSR_RI … #define MOS7840_MSR_CD … /* * Defines used for sending commands to port */ #define MOS_WDR_TIMEOUT … #define MOS_PORT1 … #define MOS_PORT2 … #define MOS_VENREG … #define MOS_MAX_PORT … #define MOS_WRITE … #define MOS_READ … /* Requests */ #define MCS_RD_RTYPE … #define MCS_WR_RTYPE … #define MCS_RDREQ … #define MCS_WRREQ … #define MCS_CTRL_TIMEOUT … #define VENDOR_READ_LENGTH … #define MAX_NAME_LEN … #define ZLP_REG1 … #define ZLP_REG5 … /* For higher baud Rates use TIOCEXBAUD */ #define TIOCEXBAUD … /* * Vendor id and device id defines * * NOTE: Do not add new defines, add entries directly to the id_table instead. */ #define USB_VENDOR_ID_BANDB … #define BANDB_DEVICE_ID_USO9ML2_2 … #define BANDB_DEVICE_ID_USO9ML2_2P … #define BANDB_DEVICE_ID_USO9ML2_4 … #define BANDB_DEVICE_ID_USO9ML2_4P … #define BANDB_DEVICE_ID_US9ML2_2 … #define BANDB_DEVICE_ID_US9ML2_4 … #define BANDB_DEVICE_ID_USPTL4_2 … #define BANDB_DEVICE_ID_USPTL4_4 … #define BANDB_DEVICE_ID_USOPTL4_2 … #define BANDB_DEVICE_ID_USOPTL4_2P … #define BANDB_DEVICE_ID_USOPTL4_4 … #define BANDB_DEVICE_ID_USOPTL4_4P … /* Interrupt Routine Defines */ #define SERIAL_IIR_RLS … #define SERIAL_IIR_MS … /* * Emulation of the bit mask on the LINE STATUS REGISTER. */ #define SERIAL_LSR_DR … #define SERIAL_LSR_OE … #define SERIAL_LSR_PE … #define SERIAL_LSR_FE … #define SERIAL_LSR_BI … #define MOS_MSR_DELTA_CTS … #define MOS_MSR_DELTA_DSR … #define MOS_MSR_DELTA_RI … #define MOS_MSR_DELTA_CD … /* Serial Port register Address */ #define INTERRUPT_ENABLE_REGISTER … #define FIFO_CONTROL_REGISTER … #define LINE_CONTROL_REGISTER … #define MODEM_CONTROL_REGISTER … #define LINE_STATUS_REGISTER … #define MODEM_STATUS_REGISTER … #define SCRATCH_PAD_REGISTER … #define DIVISOR_LATCH_LSB … #define DIVISOR_LATCH_MSB … #define CLK_MULTI_REGISTER … #define CLK_START_VALUE_REGISTER … #define GPIO_REGISTER … #define SERIAL_LCR_DLAB … /* * URB POOL related defines */ #define NUM_URBS … #define URB_TRANSFER_BUFFER_SIZE … /* LED on/off milliseconds*/ #define LED_ON_MS … #define LED_OFF_MS … enum mos7840_flag { … }; #define MCS_PORT_MASK … #define MCS_PORTS(nr) … #define MCS_LED … #define MCS_DEVICE(vid, pid, flags) … static const struct usb_device_id id_table[] = …; MODULE_DEVICE_TABLE(usb, id_table); /* This structure holds all of the local port information */ struct moschip_port { … }; /* * mos7840_set_reg_sync * To set the Control register by calling usb_fill_control_urb function * by passing usb_sndctrlpipe function as parameter. */ static int mos7840_set_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 val) { … } /* * mos7840_get_reg_sync * To set the Uart register by calling usb_fill_control_urb function by * passing usb_rcvctrlpipe function as parameter. */ static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 *val) { … } /* * mos7840_set_uart_reg * To set the Uart register by calling usb_fill_control_urb function by * passing usb_sndctrlpipe function as parameter. */ static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 val) { … } /* * mos7840_get_uart_reg * To set the Control register by calling usb_fill_control_urb function * by passing usb_rcvctrlpipe function as parameter. */ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 *val) { … } static void mos7840_dump_serial_port(struct usb_serial_port *port, struct moschip_port *mos7840_port) { … } /************************************************************************/ /************************************************************************/ /* U S B C A L L B A C K F U N C T I O N S */ /* U S B C A L L B A C K F U N C T I O N S */ /************************************************************************/ /************************************************************************/ static void mos7840_set_led_callback(struct urb *urb) { … } static void mos7840_set_led_async(struct moschip_port *mcs, __u16 wval, __u16 reg) { … } static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg, __u16 val) { … } static void mos7840_led_off(struct timer_list *t) { … } static void mos7840_led_flag_off(struct timer_list *t) { … } static void mos7840_led_activity(struct usb_serial_port *port) { … } /***************************************************************************** * mos7840_bulk_in_callback * this is the callback function for when we have received data on the * bulk in endpoint. *****************************************************************************/ static void mos7840_bulk_in_callback(struct urb *urb) { … } /***************************************************************************** * mos7840_bulk_out_data_callback * this is the callback function for when we have finished sending * serial data on the bulk out endpoint. *****************************************************************************/ static void mos7840_bulk_out_data_callback(struct urb *urb) { … } /************************************************************************/ /* D R I V E R T T Y I N T E R F A C E F U N C T I O N S */ /************************************************************************/ /***************************************************************************** * mos7840_open * this function is called by the tty driver when a port is opened * If successful, we return 0 * Otherwise we return a negative error number. *****************************************************************************/ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) { … } /***************************************************************************** * mos7840_chars_in_buffer * this function is called by the tty driver when it wants to know how many * bytes of data we currently have outstanding in the port (data that has * been written, but hasn't made it out the port yet) *****************************************************************************/ static unsigned int mos7840_chars_in_buffer(struct tty_struct *tty) { … } /***************************************************************************** * mos7840_close * this function is called by the tty driver when a port is closed *****************************************************************************/ static void mos7840_close(struct usb_serial_port *port) { … } /***************************************************************************** * mos7840_break * this function sends a break to the port *****************************************************************************/ static int mos7840_break(struct tty_struct *tty, int break_state) { … } /***************************************************************************** * mos7840_write_room * this function is called by the tty driver when it wants to know how many * bytes of data we can accept for a specific port. *****************************************************************************/ static unsigned int mos7840_write_room(struct tty_struct *tty) { … } /***************************************************************************** * mos7840_write * this function is called by the tty driver when data should be written to * the port. * If successful, we return the number of bytes written, otherwise we * return a negative error number. *****************************************************************************/ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *data, int count) { … } /***************************************************************************** * mos7840_throttle * this function is called by the tty driver when it wants to stop the data * being read from the port. *****************************************************************************/ static void mos7840_throttle(struct tty_struct *tty) { … } /***************************************************************************** * mos7840_unthrottle * this function is called by the tty driver when it wants to resume * the data being read from the port (called after mos7840_throttle is * called) *****************************************************************************/ static void mos7840_unthrottle(struct tty_struct *tty) { … } static int mos7840_tiocmget(struct tty_struct *tty) { … } static int mos7840_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { … } /***************************************************************************** * mos7840_calc_baud_rate_divisor * this function calculates the proper baud rate divisor for the specified * baud rate. *****************************************************************************/ static int mos7840_calc_baud_rate_divisor(struct usb_serial_port *port, int baudRate, int *divisor, __u16 *clk_sel_val) { … } /***************************************************************************** * mos7840_send_cmd_write_baud_rate * this function sends the proper command to change the baud rate of the * specified port. *****************************************************************************/ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, int baudRate) { … } /***************************************************************************** * mos7840_change_port_settings * This routine is called to set the UART on the device to match * the specified new settings. *****************************************************************************/ static void mos7840_change_port_settings(struct tty_struct *tty, struct moschip_port *mos7840_port, const struct ktermios *old_termios) { … } /***************************************************************************** * mos7840_set_termios * this function is called by the tty driver when it wants to change * the termios structure *****************************************************************************/ static void mos7840_set_termios(struct tty_struct *tty, struct usb_serial_port *port, const struct ktermios *old_termios) { … } /***************************************************************************** * mos7840_get_lsr_info - get line status register info * * Purpose: Let user call ioctl() to get info when the UART physically * is emptied. On bus types like RS485, the transmitter must * release the bus after transmitting. This must be done when * the transmit shift register is empty, not be done when the * transmit holding register is empty. This functionality * allows an RS485 driver to be written in user space. *****************************************************************************/ static int mos7840_get_lsr_info(struct tty_struct *tty, unsigned int __user *value) { … } /***************************************************************************** * SerialIoctl * this function handles any ioctl calls to the driver *****************************************************************************/ static int mos7840_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { … } /* * Check if GPO (pin 42) is connected to GPI (pin 33) as recommended by ASIX * for MCS7810 by bit-banging a 16-bit word. * * Note that GPO is really RTS of the third port so this will toggle RTS of * port two or three on two- and four-port devices. */ static int mos7810_check(struct usb_serial *serial) { … } static int mos7840_probe(struct usb_serial *serial, const struct usb_device_id *id) { … } static int mos7840_calc_num_ports(struct usb_serial *serial, struct usb_serial_endpoints *epds) { … } static int mos7840_attach(struct usb_serial *serial) { … } static int mos7840_port_probe(struct usb_serial_port *port) { … } static void mos7840_port_remove(struct usb_serial_port *port) { … } static int mos7840_suspend(struct usb_serial *serial, pm_message_t message) { … } static int mos7840_resume(struct usb_serial *serial) { … } static struct usb_serial_driver moschip7840_4port_device = …; static struct usb_serial_driver * const serial_drivers[] = …; module_usb_serial_driver(…); MODULE_DESCRIPTION(…); MODULE_LICENSE(…) …;