^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) * spcp8x5 USB to serial adaptor driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010-2013 Johan Hovold (jhovold@gmail.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006 Linxb (xubin.lin@worldplus.com.cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2006 S1 Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Original driver for 2.6.10 pl2303 driver by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Greg Kroah-Hartman (greg@kroah.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Changes for 2.6.20 by Harald Klein <hari@vt100.at>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/spinlock.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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define SPCP825_QUIRK_NO_UART_STATUS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SPCP825_QUIRK_NO_WORK_MODE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SPCP8x5_007_VID 0x04FC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SPCP8x5_007_PID 0x0201
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SPCP8x5_008_VID 0x04fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SPCP8x5_008_PID 0x0235
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SPCP8x5_PHILIPS_VID 0x0471
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define SPCP8x5_PHILIPS_PID 0x081e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SPCP8x5_INTERMATIC_VID 0x04FC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define SPCP8x5_INTERMATIC_PID 0x0204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SPCP8x5_835_VID 0x04fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SPCP8x5_835_PID 0x0231
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) { USB_DEVICE(SPCP8x5_PHILIPS_VID , SPCP8x5_PHILIPS_PID)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) { USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { USB_DEVICE(SPCP8x5_008_VID, SPCP8x5_008_PID)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .driver_info = SPCP825_QUIRK_NO_UART_STATUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) SPCP825_QUIRK_NO_WORK_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) MODULE_DEVICE_TABLE(usb, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct spcp8x5_usb_ctrl_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u8 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 cmd_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* spcp8x5 spec register define */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MCR_CONTROL_LINE_RTS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MCR_CONTROL_LINE_DTR 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MCR_DTR 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MCR_RTS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define MSR_STATUS_LINE_DCD 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MSR_STATUS_LINE_RI 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MSR_STATUS_LINE_DSR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define MSR_STATUS_LINE_CTS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* verdor command here , we should define myself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SET_DEFAULT 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SET_DEFAULT_TYPE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SET_UART_FORMAT 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SET_UART_FORMAT_TYPE 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SET_UART_FORMAT_SIZE_5 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SET_UART_FORMAT_SIZE_6 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SET_UART_FORMAT_SIZE_7 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SET_UART_FORMAT_SIZE_8 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SET_UART_FORMAT_STOP_1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SET_UART_FORMAT_STOP_2 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SET_UART_FORMAT_PAR_NONE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SET_UART_FORMAT_PAR_ODD 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SET_UART_FORMAT_PAR_EVEN 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define SET_UART_FORMAT_PAR_MASK 0xD0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SET_UART_FORMAT_PAR_SPACE 0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define GET_UART_STATUS_TYPE 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define GET_UART_STATUS 0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define GET_UART_STATUS_MSR 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SET_UART_STATUS 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SET_UART_STATUS_TYPE 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SET_UART_STATUS_MCR 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define SET_UART_STATUS_MCR_DTR 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define SET_UART_STATUS_MCR_RTS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define SET_UART_STATUS_MCR_LOOP 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SET_WORKING_MODE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define SET_WORKING_MODE_TYPE 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define SET_WORKING_MODE_U2C 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define SET_WORKING_MODE_RS485 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define SET_WORKING_MODE_PDMA 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define SET_WORKING_MODE_SPP 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define SET_FLOWCTL_CHAR 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define SET_FLOWCTL_CHAR_TYPE 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define GET_VERSION 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define GET_VERSION_TYPE 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define SET_REGISTER 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define SET_REGISTER_TYPE 0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define GET_REGISTER 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define GET_REGISTER_TYPE 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define SET_RAM 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define SET_RAM_TYPE 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define GET_RAM 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define GET_RAM_TYPE 0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* how come ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define UART_STATE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define UART_STATE_TRANSIENT_MASK 0x75
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define UART_DCD 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define UART_DSR 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define UART_BREAK_ERROR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define UART_RING 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define UART_FRAME_ERROR 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define UART_PARITY_ERROR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define UART_OVERRUN_ERROR 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define UART_CTS 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct spcp8x5_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u8 line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int spcp8x5_probe(struct usb_serial *serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) usb_set_serial_data(serial, (void *)id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int spcp8x5_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) const struct usb_device_id *id = usb_get_serial_data(port->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct spcp8x5_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) priv = kzalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) spin_lock_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) priv->quirks = id->driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) usb_set_serial_port_data(port, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) port->port.drain_delay = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int spcp8x5_port_remove(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct spcp8x5_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int spcp8x5_set_ctrl_line(struct usb_serial_port *port, u8 mcr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct usb_device *dev = port->serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (priv->quirks & SPCP825_QUIRK_NO_UART_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) SET_UART_STATUS_TYPE, SET_UART_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mcr, 0x04, NULL, 0, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev_err(&port->dev, "failed to set control lines: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct usb_device *dev = port->serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (priv->quirks & SPCP825_QUIRK_NO_UART_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) buf = kzalloc(1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) GET_UART_STATUS, GET_UART_STATUS_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 0, GET_UART_STATUS_MSR, buf, 1, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (ret < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dev_err(&port->dev, "failed to get modem status: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) goto out;
^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) dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *status = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static void spcp8x5_set_work_mode(struct usb_serial_port *port, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u16 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct usb_device *dev = port->serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (priv->quirks & SPCP825_QUIRK_NO_WORK_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) SET_WORKING_MODE_TYPE, SET_WORKING_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) value, index, NULL, 0, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_dbg(&port->dev, "value = %#x , index = %#x\n", value, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) dev_err(&port->dev, "failed to set work mode: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int spcp8x5_carrier_raised(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u8 msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = spcp8x5_get_msr(port, &msr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret || msr & MSR_STATUS_LINE_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^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) static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u8 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) priv->line_control = MCR_CONTROL_LINE_DTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) | MCR_CONTROL_LINE_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) priv->line_control &= ~ (MCR_CONTROL_LINE_DTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) | MCR_CONTROL_LINE_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) control = priv->line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) spcp8x5_set_ctrl_line(port, control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static void spcp8x5_init_termios(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) tty_encode_baud_rate(tty, 115200, 115200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static void spcp8x5_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct usb_serial_port *port, struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) unsigned int cflag = tty->termios.c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) unsigned short uartdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) unsigned char buf[2] = {0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u8 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* check that they really want us to change something */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* set DTR/RTS active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) control = priv->line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (old_termios && (old_termios->c_cflag & CBAUD) == B0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) priv->line_control |= MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (!(old_termios->c_cflag & CRTSCTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) priv->line_control |= MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (control != priv->line_control) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) control = priv->line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) spcp8x5_set_ctrl_line(port, control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Set Baud Rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) baud = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) switch (baud) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case 300: buf[0] = 0x00; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) case 600: buf[0] = 0x01; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case 1200: buf[0] = 0x02; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) case 2400: buf[0] = 0x03; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) case 4800: buf[0] = 0x04; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case 9600: buf[0] = 0x05; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) case 19200: buf[0] = 0x07; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case 38400: buf[0] = 0x09; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case 57600: buf[0] = 0x0a; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case 115200: buf[0] = 0x0b; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case 230400: buf[0] = 0x0c; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case 460800: buf[0] = 0x0d; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case 921600: buf[0] = 0x0e; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* case 1200000: buf[0] = 0x0f; break; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* case 2400000: buf[0] = 0x10; break; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) case 3000000: buf[0] = 0x11; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* case 6000000: buf[0] = 0x12; break; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) case 1000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) buf[0] = 0x0b; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev_err(&port->dev, "unsupported baudrate, using 9600\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) buf[1] |= SET_UART_FORMAT_SIZE_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) buf[1] |= SET_UART_FORMAT_SIZE_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) buf[1] |= SET_UART_FORMAT_SIZE_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) buf[1] |= SET_UART_FORMAT_SIZE_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^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) /* Set Stop bit2 : 0:1bit 1:2bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) buf[1] |= (cflag & CSTOPB) ? SET_UART_FORMAT_STOP_2 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) SET_UART_FORMAT_STOP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* Set Parity bit3-4 01:Odd 11:Even */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (cflag & PARENB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) buf[1] |= (cflag & PARODD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) SET_UART_FORMAT_PAR_ODD : SET_UART_FORMAT_PAR_EVEN ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) buf[1] |= SET_UART_FORMAT_PAR_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) uartdata = buf[0] | buf[1]<<8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) SET_UART_FORMAT_TYPE, SET_UART_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) uartdata, 0, NULL, 0, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) uartdata, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) dev_dbg(&port->dev, "0x21:0x40:0:0 %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (cflag & CRTSCTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* enable hardware flow control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) spcp8x5_set_work_mode(port, 0x000a, SET_WORKING_MODE_U2C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) usb_clear_halt(serial->dev, port->write_urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) usb_clear_halt(serial->dev, port->read_urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 0x09, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 0x01, 0x00, NULL, 0x00, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) spcp8x5_set_ctrl_line(port, priv->line_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) spcp8x5_set_termios(tty, port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return usb_serial_generic_open(tty, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static int spcp8x5_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) u8 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) priv->line_control |= MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) priv->line_control |= MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) priv->line_control &= ~MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) priv->line_control &= ~MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) control = priv->line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return spcp8x5_set_ctrl_line(port, control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int spcp8x5_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct spcp8x5_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned int mcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) result = spcp8x5_get_msr(port, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) mcr = priv->line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) | ((status & MSR_STATUS_LINE_CTS) ? TIOCM_CTS : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) | ((status & MSR_STATUS_LINE_DSR) ? TIOCM_DSR : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) | ((status & MSR_STATUS_LINE_RI) ? TIOCM_RI : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) | ((status & MSR_STATUS_LINE_DCD) ? TIOCM_CD : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static struct usb_serial_driver spcp8x5_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .name = "SPCP8x5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .num_bulk_in = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .num_bulk_out = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .open = spcp8x5_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .dtr_rts = spcp8x5_dtr_rts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .carrier_raised = spcp8x5_carrier_raised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .set_termios = spcp8x5_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .init_termios = spcp8x5_init_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .tiocmget = spcp8x5_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .tiocmset = spcp8x5_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .probe = spcp8x5_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .port_probe = spcp8x5_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .port_remove = spcp8x5_port_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) &spcp8x5_device, NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) module_usb_serial_driver(serial_drivers, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) MODULE_LICENSE("GPL");