^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Fintek F81232 USB to serial adaptor driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Fintek F81532A/534A/535/536 USB to 2/4/8/12 serial adaptor driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2012 Greg Kroah-Hartman (gregkh@linuxfoundation.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2012 Linux Foundation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/serial_reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define F81232_ID \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) { USB_DEVICE(0x1934, 0x0706) } /* 1 port UART device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define F81534A_SERIES_ID \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) { USB_DEVICE(0x2c42, 0x1602) }, /* In-Box 2 port UART device */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) { USB_DEVICE(0x2c42, 0x1604) }, /* In-Box 4 port UART device */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) { USB_DEVICE(0x2c42, 0x1605) }, /* In-Box 8 port UART device */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { USB_DEVICE(0x2c42, 0x1606) }, /* In-Box 12 port UART device */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { USB_DEVICE(0x2c42, 0x1608) }, /* Non-Flash type */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { USB_DEVICE(0x2c42, 0x1632) }, /* 2 port UART device */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { USB_DEVICE(0x2c42, 0x1634) }, /* 4 port UART device */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { USB_DEVICE(0x2c42, 0x1635) }, /* 8 port UART device */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) { USB_DEVICE(0x2c42, 0x1636) } /* 12 port UART device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define F81534A_CTRL_ID \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) { USB_DEVICE(0x2c42, 0x16f8) } /* Global control device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const struct usb_device_id f81232_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) F81232_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static const struct usb_device_id f81534a_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) F81534A_SERIES_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static const struct usb_device_id f81534a_ctrl_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) F81534A_CTRL_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const struct usb_device_id combined_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) F81232_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) F81534A_SERIES_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) F81534A_CTRL_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) MODULE_DEVICE_TABLE(usb, combined_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Maximum baudrate for F81232 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define F81232_MAX_BAUDRATE 1500000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define F81232_DEF_BAUDRATE 9600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* USB Control EP parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define F81232_REGISTER_REQUEST 0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define F81232_GET_REGISTER 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define F81232_SET_REGISTER 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define F81534A_ACCESS_REG_RETRY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SERIAL_BASE_ADDRESS 0x0120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define RECEIVE_BUFFER_REGISTER (0x00 + SERIAL_BASE_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LINE_STATUS_REGISTER (0x05 + SERIAL_BASE_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * F81232 Clock registers (106h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Bit1-0: Clock source selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * 00: 1.846MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * 01: 18.46MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * 10: 24MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * 11: 14.77MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define F81232_CLK_REGISTER 0x106
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define F81232_CLK_1_846_MHZ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define F81232_CLK_18_46_MHZ BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define F81232_CLK_24_MHZ BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define F81232_CLK_14_77_MHZ (BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define F81232_CLK_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define F81534A_MODE_REG 0x107
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define F81534A_TRIGGER_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define F81534A_TRIGGER_MULTIPLE_4X BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define F81534A_FIFO_128BYTE (BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Serial port self GPIO control, 2bytes [control&output data][input data] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define F81534A_GPIO_REG 0x10e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define F81534A_GPIO_MODE2_DIR BIT(6) /* 1: input, 0: output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define F81534A_GPIO_MODE1_DIR BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define F81534A_GPIO_MODE0_DIR BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define F81534A_GPIO_MODE2_OUTPUT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define F81534A_GPIO_MODE1_OUTPUT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define F81534A_GPIO_MODE0_OUTPUT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define F81534A_CTRL_CMD_ENABLE_PORT 0x116
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct f81232_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 modem_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 modem_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 shadow_lcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) speed_t baud_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct work_struct lsr_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct work_struct interrupt_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static u32 const baudrate_table[] = { 115200, 921600, 1152000, 1500000 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static u8 const clock_table[] = { F81232_CLK_1_846_MHZ, F81232_CLK_14_77_MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) F81232_CLK_18_46_MHZ, F81232_CLK_24_MHZ };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!baudrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return DIV_ROUND_CLOSEST(clockrate, baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u8 *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct usb_device *dev = port->serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) tmp = kmalloc(sizeof(*val), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) status = usb_control_msg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) usb_rcvctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) F81232_REGISTER_REQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) F81232_GET_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) sizeof(*val),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) USB_CTRL_GET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (status != sizeof(*val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) status = usb_translate_errors(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *val = *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) kfree(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u8 *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct usb_device *dev = port->serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) tmp = kmalloc(sizeof(val), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *tmp = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) status = usb_control_msg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) usb_sndctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) F81232_REGISTER_REQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) F81232_SET_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) sizeof(val),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (status != sizeof(val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) status = usb_translate_errors(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) kfree(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int f81232_set_mask_register(struct usb_serial_port *port, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u8 mask, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) status = f81232_get_register(port, reg, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) tmp = (tmp & ~mask) | (val & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return f81232_set_register(port, reg, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void f81232_read_msr(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u8 current_msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mutex_lock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) status = f81232_get_register(port, MODEM_STATUS_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ¤t_msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dev_err(&port->dev, "%s fail, status: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!(current_msr & UART_MSR_ANY_DELTA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) priv->modem_status = current_msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (current_msr & UART_MSR_DCTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) port->icount.cts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (current_msr & UART_MSR_DDSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) port->icount.dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (current_msr & UART_MSR_TERI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) port->icount.rng++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (current_msr & UART_MSR_DDCD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) port->icount.dcd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) tty = tty_port_tty_get(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) usb_serial_handle_dcd_change(port, tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) current_msr & UART_MSR_DCD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) wake_up_interruptible(&port->port.delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static int f81232_set_mctrl(struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 0; /* no change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* 'set' takes precedence over 'clear' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) clear &= ~set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* force enable interrupt with OUT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mutex_lock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) val = UART_MCR_OUT2 | priv->modem_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) val &= ~UART_MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) val &= ~UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) val |= UART_MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) val |= UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dev_dbg(&port->dev, "%s new:%02x old:%02x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) val, priv->modem_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) status = f81232_set_register(port, MODEM_CONTROL_REGISTER, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_err(&port->dev, "%s set MCR status < 0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) priv->modem_control = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void f81232_update_line_status(struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) unsigned char *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) size_t actual_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!actual_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) switch (data[0] & 0x07) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) case 0x00: /* msr change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dev_dbg(&port->dev, "IIR: MSR Change: %02x\n", data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) schedule_work(&priv->interrupt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case 0x02: /* tx-empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case 0x04: /* rx data available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case 0x06: /* lsr change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* we can forget it. the LSR will read from bulk-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev_dbg(&port->dev, "IIR: LSR Change: %02x\n", data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static void f81232_read_int_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unsigned int actual_length = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* this urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) usb_serial_debug_data(&port->dev, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) urb->actual_length, urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) f81232_update_line_status(port, data, actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) retval = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) dev_err(&urb->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) "%s - usb_submit_urb failed with result %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) __func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static char f81232_handle_lsr(struct usb_serial_port *port, u8 lsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) char tty_flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (!(lsr & UART_LSR_BRK_ERROR_BITS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return tty_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (lsr & UART_LSR_BI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) tty_flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) usb_serial_handle_break(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) } else if (lsr & UART_LSR_PE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) tty_flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) port->icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) } else if (lsr & UART_LSR_FE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) tty_flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (lsr & UART_LSR_OE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) port->icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) schedule_work(&priv->lsr_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return tty_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static void f81232_process_read_urb(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) char tty_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) u8 lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * When opening the port we get a 1-byte packet with the current LSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * which we discard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if ((urb->actual_length < 2) || (urb->actual_length % 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) for (i = 0; i < urb->actual_length; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) lsr = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) tty_flag = f81232_handle_lsr(port, lsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (port->sysrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (usb_serial_handle_sysrq_char(port, data[i + 1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) tty_insert_flip_char(&port->port, data[i + 1], tty_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static void f81534a_process_read_urb(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) char tty_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) u8 lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (urb->actual_length < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dev_err(&port->dev, "short message received: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) len = data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (len != urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_err(&port->dev, "malformed message received: %d (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) urb->actual_length, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* bulk-in data: [LEN][Data.....][LSR] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) lsr = data[len - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) tty_flag = f81232_handle_lsr(port, lsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (port->sysrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) for (i = 1; i < len - 1; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!usb_serial_handle_sysrq_char(port, data[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) tty_insert_flip_char(&port->port, data[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) tty_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) tty_insert_flip_string_fixed_flag(&port->port, &data[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) tty_flag, len - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void f81232_break_ctl(struct tty_struct *tty, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) mutex_lock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) priv->shadow_lcr |= UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) priv->shadow_lcr &= ~UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) status = f81232_set_register(port, LINE_CONTROL_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) priv->shadow_lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev_err(&port->dev, "set break failed: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int f81232_find_clk(speed_t baudrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (baudrate <= baudrate_table[idx] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) baudrate_table[idx] % baudrate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static void f81232_set_baudrate(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct usb_serial_port *port, speed_t baudrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) speed_t old_baudrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) u8 lcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) speed_t baud_list[] = { baudrate, old_baudrate, F81232_DEF_BAUDRATE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) idx = f81232_find_clk(baud_list[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (idx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) baudrate = baud_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) tty_encode_baud_rate(tty, baudrate, baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) priv->baud_base = baudrate_table[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) divisor = calc_baud_divisor(baudrate, priv->baud_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) status = f81232_set_mask_register(port, F81232_CLK_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) F81232_CLK_MASK, clock_table[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) dev_err(&port->dev, "%s failed to set CLK_REG: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) status = f81232_get_register(port, LINE_CONTROL_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) &lcr); /* get LCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dev_err(&port->dev, "%s failed to get LCR: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) status = f81232_set_register(port, LINE_CONTROL_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) lcr | UART_LCR_DLAB); /* Enable DLAB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) dev_err(&port->dev, "%s failed to set DLAB: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) status = f81232_set_register(port, RECEIVE_BUFFER_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) divisor & 0x00ff); /* low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) dev_err(&port->dev, "%s failed to set baudrate MSB: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) goto reapply_lcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) (divisor & 0xff00) >> 8); /* high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) dev_err(&port->dev, "%s failed to set baudrate LSB: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) reapply_lcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) status = f81232_set_register(port, LINE_CONTROL_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) lcr & ~UART_LCR_DLAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) dev_err(&port->dev, "%s failed to set DLAB: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int f81232_port_enable(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* fifo on, trigger8, clear TX/RX*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) val = UART_FCR_TRIGGER_8 | UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) UART_FCR_CLEAR_XMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) status = f81232_set_register(port, FIFO_CONTROL_REGISTER, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dev_err(&port->dev, "%s failed to set FCR: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* MSR Interrupt only, LSR will read from Bulk-in odd byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) UART_IER_MSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dev_err(&port->dev, "%s failed to set IER: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int f81232_port_disable(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev_err(&port->dev, "%s failed to set IER: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static void f81232_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct usb_serial_port *port, struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) u8 new_lcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) speed_t baudrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) speed_t old_baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* Don't change anything if nothing has changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (C_BAUD(tty) == B0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) baudrate = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (baudrate > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) old_baud = tty_termios_baud_rate(old_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) old_baud = F81232_DEF_BAUDRATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) f81232_set_baudrate(tty, port, baudrate, old_baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (C_PARENB(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) new_lcr |= UART_LCR_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (!C_PARODD(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) new_lcr |= UART_LCR_EPAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (C_CMSPAR(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) new_lcr |= UART_LCR_SPAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (C_CSTOPB(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) new_lcr |= UART_LCR_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) switch (C_CSIZE(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) new_lcr |= UART_LCR_WLEN5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) new_lcr |= UART_LCR_WLEN6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) new_lcr |= UART_LCR_WLEN7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) new_lcr |= UART_LCR_WLEN8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) mutex_lock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) new_lcr |= (priv->shadow_lcr & UART_LCR_SBC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) status = f81232_set_register(port, LINE_CONTROL_REGISTER, new_lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) dev_err(&port->dev, "%s failed to set LCR: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) priv->shadow_lcr = new_lcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int f81232_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct f81232_private *port_priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) u8 mcr, msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* force get current MSR changed state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) f81232_read_msr(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) mutex_lock(&port_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) mcr = port_priv->modem_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) msr = port_priv->modem_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) mutex_unlock(&port_priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) r = (mcr & UART_MCR_DTR ? TIOCM_DTR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) (mcr & UART_MCR_RTS ? TIOCM_RTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) (msr & UART_MSR_CTS ? TIOCM_CTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) (msr & UART_MSR_DCD ? TIOCM_CAR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) (msr & UART_MSR_RI ? TIOCM_RI : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) (msr & UART_MSR_DSR ? TIOCM_DSR : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static int f81232_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return f81232_set_mctrl(port, set, clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) result = f81232_port_enable(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* Setup termios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) f81232_set_termios(tty, port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) dev_err(&port->dev, "%s - failed submitting interrupt urb,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) " error %d\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) result = usb_serial_generic_open(tty, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static int f81534a_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) val = F81534A_TRIGGER_MULTIPLE_4X | F81534A_FIFO_128BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) mask = F81534A_TRIGGER_MASK | F81534A_FIFO_128BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) status = f81232_set_mask_register(port, F81534A_MODE_REG, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dev_err(&port->dev, "failed to set MODE_REG: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return f81232_open(tty, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) static void f81232_close(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct f81232_private *port_priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) f81232_port_disable(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) usb_serial_generic_close(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) flush_work(&port_priv->interrupt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) flush_work(&port_priv->lsr_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static void f81232_dtr_rts(struct usb_serial_port *port, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static bool f81232_tx_empty(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) status = f81232_get_register(port, LINE_STATUS_REGISTER, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if ((tmp & UART_LSR_TEMT) != UART_LSR_TEMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static int f81232_carrier_raised(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) u8 msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) mutex_lock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) msr = priv->modem_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (msr & UART_MSR_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int f81232_get_serial_info(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct serial_struct *ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct f81232_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ss->type = PORT_16550A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) ss->line = port->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) ss->port = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ss->baud_base = priv->baud_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static void f81232_interrupt_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct f81232_private *priv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) container_of(work, struct f81232_private, interrupt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) f81232_read_msr(priv->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static void f81232_lsr_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct f81232_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) priv = container_of(work, struct f81232_private, lsr_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) port = priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) status = f81232_get_register(port, LINE_STATUS_REGISTER, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) dev_warn(&port->dev, "read LSR failed: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u16 size, void *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct usb_device *dev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) int retry = F81534A_ACCESS_REG_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) u8 *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) tmp = kmemdup(val, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) while (retry--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) status = usb_control_msg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) usb_sndctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) F81232_REGISTER_REQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) F81232_SET_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) status = usb_translate_errors(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (status == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) } else if (status != size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* Retry on short transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) dev_err(&intf->dev, "failed to set register 0x%x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) reg, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) kfree(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int f81534a_ctrl_enable_all_ports(struct usb_interface *intf, bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) unsigned char enable[2] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * Enable all available serial ports, define as following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * bit 15 : Reset behavior (when HUB got soft reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * 0: maintain all serial port enabled state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * 1: disable all serial port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * bit 0~11 : Serial port enable bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) enable[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) enable[1] = 0x8f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) status = f81534a_ctrl_set_register(intf, F81534A_CTRL_CMD_ENABLE_PORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) sizeof(enable), enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) dev_err(&intf->dev, "failed to enable ports: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static int f81534a_ctrl_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return f81534a_ctrl_enable_all_ports(intf, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static void f81534a_ctrl_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) f81534a_ctrl_enable_all_ports(intf, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static int f81534a_ctrl_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return f81534a_ctrl_enable_all_ports(intf, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static int f81232_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct f81232_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) priv = devm_kzalloc(&port->dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) mutex_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) INIT_WORK(&priv->interrupt_work, f81232_interrupt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) INIT_WORK(&priv->lsr_work, f81232_lsr_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) usb_set_serial_port_data(port, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) port->port.drain_delay = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) priv->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static int f81534a_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /* tri-state with pull-high, default RS232 Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) status = f81232_set_register(port, F81534A_GPIO_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) F81534A_GPIO_MODE2_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return f81232_port_probe(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static int f81232_suspend(struct usb_serial *serial, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct usb_serial_port *port = serial->port[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct f81232_private *port_priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) usb_kill_urb(port->read_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (port_priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) flush_work(&port_priv->interrupt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) flush_work(&port_priv->lsr_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static int f81232_resume(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct usb_serial_port *port = serial->port[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (tty_port_initialized(&port->port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) dev_err(&port->dev, "submit interrupt urb failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return usb_serial_generic_resume(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static struct usb_serial_driver f81232_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .name = "f81232",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .id_table = f81232_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .bulk_in_size = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .bulk_out_size = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .open = f81232_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .close = f81232_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .dtr_rts = f81232_dtr_rts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .carrier_raised = f81232_carrier_raised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .get_serial = f81232_get_serial_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .break_ctl = f81232_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .set_termios = f81232_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .tiocmget = f81232_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .tiocmset = f81232_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .tiocmiwait = usb_serial_generic_tiocmiwait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .tx_empty = f81232_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .process_read_urb = f81232_process_read_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .read_int_callback = f81232_read_int_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .port_probe = f81232_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .suspend = f81232_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .resume = f81232_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) static struct usb_serial_driver f81534a_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) .name = "f81534a",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .id_table = f81534a_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .open = f81534a_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .close = f81232_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .dtr_rts = f81232_dtr_rts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .carrier_raised = f81232_carrier_raised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .get_serial = f81232_get_serial_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .break_ctl = f81232_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .set_termios = f81232_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .tiocmget = f81232_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .tiocmset = f81232_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .tiocmiwait = usb_serial_generic_tiocmiwait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .tx_empty = f81232_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .process_read_urb = f81534a_process_read_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .read_int_callback = f81232_read_int_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .port_probe = f81534a_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .suspend = f81232_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .resume = f81232_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) &f81232_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) &f81534a_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static struct usb_driver f81534a_ctrl_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .name = "f81534a_ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .id_table = f81534a_ctrl_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .probe = f81534a_ctrl_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .disconnect = f81534a_ctrl_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .resume = f81534a_ctrl_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static int __init f81232_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) status = usb_register_driver(&f81534a_ctrl_driver, THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) KBUILD_MODNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) status = usb_serial_register_drivers(serial_drivers, KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) combined_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) usb_deregister(&f81534a_ctrl_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static void __exit f81232_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) usb_serial_deregister_drivers(serial_drivers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) usb_deregister(&f81534a_ctrl_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) module_init(f81232_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) module_exit(f81232_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) MODULE_DESCRIPTION("Fintek F81232/532A/534A/535/536 USB to serial driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) MODULE_AUTHOR("Peter Hong <peter_hong@fintek.com.tw>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) MODULE_LICENSE("GPL v2");