Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");