Staging: quatech_usb2: vendor implementation of set_termios method
This patch imports the implementation of the set_termios method from the vendor driver into the staging driver. The common terminal setting changes should be supported. Signed-off-by: Richard Ash <richard@audacityteam.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
2feb633d65
commit
2715dd6a93
|
@ -52,12 +52,12 @@ static int debug;
|
||||||
#define QT_OPEN_CLOSE_CHANNEL 0xca
|
#define QT_OPEN_CLOSE_CHANNEL 0xca
|
||||||
/*#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
|
/*#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
|
||||||
#define QT_SET_ATF 0xcd*/
|
#define QT_SET_ATF 0xcd*/
|
||||||
#define QT2_GET_SET_REGISTER 0xc0
|
#define QT2_GET_SET_REGISTER 0xc0
|
||||||
#define QT_GET_SET_UART 0xc1
|
#define QT2_GET_SET_UART 0xc1
|
||||||
/*#define QT_HW_FLOW_CONTROL_MASK 0xc5
|
#define QT2_HW_FLOW_CONTROL_MASK 0xc5
|
||||||
#define QT_SW_FLOW_CONTROL_MASK 0xc6
|
#define QT2_SW_FLOW_CONTROL_MASK 0xc6
|
||||||
#define QT_SW_FLOW_CONTROL_DISABLE 0xc7
|
#define QT2_SW_FLOW_CONTROL_DISABLE 0xc7
|
||||||
#define QT_BREAK_CONTROL 0xc8
|
/*#define QT_BREAK_CONTROL 0xc8
|
||||||
#define QT_STOP_RECEIVE 0xe0*/
|
#define QT_STOP_RECEIVE 0xe0*/
|
||||||
#define QT2_FLUSH_DEVICE 0xc4
|
#define QT2_FLUSH_DEVICE 0xc4
|
||||||
#define QT_GET_SET_QMCR 0xe1
|
#define QT_GET_SET_QMCR 0xe1
|
||||||
|
@ -66,34 +66,35 @@ static int debug;
|
||||||
#define QT2_FLUSH_RX 0x00
|
#define QT2_FLUSH_RX 0x00
|
||||||
#define QT2_FLUSH_TX 0x01
|
#define QT2_FLUSH_TX 0x01
|
||||||
|
|
||||||
/* port setting constants */
|
/* port setting constants, used to set up serial port speeds, flow
|
||||||
#define SERIAL_MCR_DTR 0x01
|
* control and so on */
|
||||||
#define SERIAL_MCR_RTS 0x02
|
#define QT2_SERIAL_MCR_DTR 0x01
|
||||||
#define SERIAL_MCR_LOOP 0x10
|
#define QT2_SERIAL_MCR_RTS 0x02
|
||||||
|
#define QT2_SERIAL_MCR_LOOP 0x10
|
||||||
|
|
||||||
#define SERIAL_MSR_CTS 0x10
|
#define QT2_SERIAL_MSR_CTS 0x10
|
||||||
#define SERIAL_MSR_CD 0x80
|
#define QT2_SERIAL_MSR_CD 0x80
|
||||||
#define SERIAL_MSR_RI 0x40
|
#define QT2_SERIAL_MSR_RI 0x40
|
||||||
#define SERIAL_MSR_DSR 0x20
|
#define QT2_SERIAL_MSR_DSR 0x20
|
||||||
#define SERIAL_MSR_MASK 0xf0
|
#define QT2_SERIAL_MSR_MASK 0xf0
|
||||||
|
|
||||||
#define SERIAL_8_DATA 0x03
|
#define QT2_SERIAL_8_DATA 0x03
|
||||||
#define SERIAL_7_DATA 0x02
|
#define QT2_SERIAL_7_DATA 0x02
|
||||||
#define SERIAL_6_DATA 0x01
|
#define QT2_SERIAL_6_DATA 0x01
|
||||||
#define SERIAL_5_DATA 0x00
|
#define QT2_SERIAL_5_DATA 0x00
|
||||||
|
|
||||||
#define SERIAL_ODD_PARITY 0X08
|
#define QT2_SERIAL_ODD_PARITY 0X08
|
||||||
#define SERIAL_EVEN_PARITY 0X18
|
#define QT2_SERIAL_EVEN_PARITY 0X18
|
||||||
#define SERIAL_TWO_STOPB 0x04
|
#define QT2_SERIAL_TWO_STOPB 0x04
|
||||||
#define SERIAL_ONE_STOPB 0x00
|
#define QT2_SERIAL_ONE_STOPB 0x00
|
||||||
|
|
||||||
#define MAX_BAUD_RATE 921600
|
#define QT2_MAX_BAUD_RATE 921600
|
||||||
#define MAX_BAUD_REMAINDER 4608
|
#define QT2_MAX_BAUD_REMAINDER 4608
|
||||||
|
|
||||||
#define SERIAL_LSR_OE 0x02
|
#define QT2_SERIAL_LSR_OE 0x02
|
||||||
#define SERIAL_LSR_PE 0x04
|
#define QT2_SERIAL_LSR_PE 0x04
|
||||||
#define SERIAL_LSR_FE 0x08
|
#define QT2_SERIAL_LSR_FE 0x08
|
||||||
#define SERIAL_LSR_BI 0x10
|
#define QT2_SERIAL_LSR_BI 0x10
|
||||||
|
|
||||||
/* value of Line Status Register when UART has completed
|
/* value of Line Status Register when UART has completed
|
||||||
* emptying data out on the line */
|
* emptying data out on the line */
|
||||||
|
@ -268,11 +269,18 @@ static int qt2_box_set_register(struct usb_serial *serial,
|
||||||
unsigned short Value);
|
unsigned short Value);
|
||||||
static int qt2_box_flush(struct usb_serial *serial, unsigned char uart_number,
|
static int qt2_box_flush(struct usb_serial *serial, unsigned char uart_number,
|
||||||
unsigned short rcv_or_xmit);
|
unsigned short rcv_or_xmit);
|
||||||
static int qt2_write(struct tty_struct *tty, struct usb_serial_port *port,
|
static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
|
||||||
|
unsigned short default_divisor, unsigned char default_LCR);
|
||||||
|
/*static int qt2_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||||
const unsigned char *buf, int count);
|
const unsigned char *buf, int count);
|
||||||
static int qt2_tiocmget(struct tty_struct *tty, struct file *file);
|
static int qt2_tiocmget(struct tty_struct *tty, struct file *file);
|
||||||
static int qt2_tiocmset(struct tty_struct *tty, struct file *file,
|
static int qt2_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
unsigned int set, unsigned int clear);
|
unsigned int set, unsigned int clear);*/
|
||||||
|
static int qt2_boxsethw_flowctl(struct usb_serial *serial,
|
||||||
|
unsigned int UartNumber, bool bSet);
|
||||||
|
static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber,
|
||||||
|
unsigned char stop_char, unsigned char start_char);
|
||||||
|
static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber);
|
||||||
|
|
||||||
/* implementation functions, roughly in order of use, are here */
|
/* implementation functions, roughly in order of use, are here */
|
||||||
static int qt2_calc_num_ports(struct usb_serial *serial)
|
static int qt2_calc_num_ports(struct usb_serial *serial)
|
||||||
|
@ -452,7 +460,7 @@ int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||||
struct quatech2_dev *dev_extra; /* extra data for the device */
|
struct quatech2_dev *dev_extra; /* extra data for the device */
|
||||||
struct qt2_status_data ChannelData;
|
struct qt2_status_data ChannelData;
|
||||||
unsigned short default_divisor = QU2BOXSPD9600;
|
unsigned short default_divisor = QU2BOXSPD9600;
|
||||||
unsigned char default_LCR = SERIAL_8_DATA;
|
unsigned char default_LCR = QT2_SERIAL_8_DATA;
|
||||||
int status;
|
int status;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -495,11 +503,11 @@ int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
port_extra->shadowLSR = ChannelData.line_status &
|
port_extra->shadowLSR = ChannelData.line_status &
|
||||||
(SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
|
(QT2_SERIAL_LSR_OE | QT2_SERIAL_LSR_PE |
|
||||||
SERIAL_LSR_BI);
|
QT2_SERIAL_LSR_FE | QT2_SERIAL_LSR_BI);
|
||||||
port_extra->shadowMSR = ChannelData.modem_status &
|
port_extra->shadowMSR = ChannelData.modem_status &
|
||||||
(SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI |
|
(QT2_SERIAL_MSR_CTS | QT2_SERIAL_MSR_DSR |
|
||||||
SERIAL_MSR_CD);
|
QT2_SERIAL_MSR_RI | QT2_SERIAL_MSR_CD);
|
||||||
|
|
||||||
/* port_extra->fifo_empty_flag = true;*/
|
/* port_extra->fifo_empty_flag = true;*/
|
||||||
dbg("qt2_openboxchannel on channel %d completed.",
|
dbg("qt2_openboxchannel on channel %d completed.",
|
||||||
|
@ -884,19 +892,19 @@ static int qt2_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TIOCMBIS:
|
case TIOCMBIS:
|
||||||
if (value & TIOCM_RTS)
|
if (value & TIOCM_RTS)
|
||||||
mcr_value |= SERIAL_MCR_RTS;
|
mcr_value |= QT2_SERIAL_MCR_RTS;
|
||||||
if (value & TIOCM_DTR)
|
if (value & TIOCM_DTR)
|
||||||
mcr_value |= SERIAL_MCR_DTR;
|
mcr_value |= QT2_SERIAL_MCR_DTR;
|
||||||
if (value & TIOCM_LOOP)
|
if (value & TIOCM_LOOP)
|
||||||
mcr_value |= SERIAL_MCR_LOOP;
|
mcr_value |= QT2_SERIAL_MCR_LOOP;
|
||||||
break;
|
break;
|
||||||
case TIOCMBIC:
|
case TIOCMBIC:
|
||||||
if (value & TIOCM_RTS)
|
if (value & TIOCM_RTS)
|
||||||
mcr_value &= ~SERIAL_MCR_RTS;
|
mcr_value &= ~QT2_SERIAL_MCR_RTS;
|
||||||
if (value & TIOCM_DTR)
|
if (value & TIOCM_DTR)
|
||||||
mcr_value &= ~SERIAL_MCR_DTR;
|
mcr_value &= ~QT2_SERIAL_MCR_DTR;
|
||||||
if (value & TIOCM_LOOP)
|
if (value & TIOCM_LOOP)
|
||||||
mcr_value &= ~SERIAL_MCR_LOOP;
|
mcr_value &= ~QT2_SERIAL_MCR_LOOP;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -911,7 +919,7 @@ static int qt2_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
} else if (cmd == TIOCMIWAIT) {
|
} else if (cmd == TIOCMIWAIT) {
|
||||||
dbg("%s() port %d, cmd == TIOCMIWAIT enter",
|
dbg("%s() port %d, cmd == TIOCMIWAIT enter",
|
||||||
__func__, port->number);
|
__func__, port->number);
|
||||||
prev_msr_value = port_extra->shadowMSR & SERIAL_MSR_MASK;
|
prev_msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK;
|
||||||
while (1) {
|
while (1) {
|
||||||
add_wait_queue(&port_extra->wait, &wait);
|
add_wait_queue(&port_extra->wait, &wait);
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
@ -922,21 +930,21 @@ static int qt2_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
/* see if a signal woke us up */
|
/* see if a signal woke us up */
|
||||||
if (signal_pending(current))
|
if (signal_pending(current))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
msr_value = port_extra->shadowMSR & SERIAL_MSR_MASK;
|
msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK;
|
||||||
if (msr_value == prev_msr_value)
|
if (msr_value == prev_msr_value)
|
||||||
return -EIO; /* no change - error */
|
return -EIO; /* no change - error */
|
||||||
if ((arg & TIOCM_RNG &&
|
if ((arg & TIOCM_RNG &&
|
||||||
((prev_msr_value & SERIAL_MSR_RI) ==
|
((prev_msr_value & QT2_SERIAL_MSR_RI) ==
|
||||||
(msr_value & SERIAL_MSR_RI))) ||
|
(msr_value & QT2_SERIAL_MSR_RI))) ||
|
||||||
(arg & TIOCM_DSR &&
|
(arg & TIOCM_DSR &&
|
||||||
((prev_msr_value & SERIAL_MSR_DSR) ==
|
((prev_msr_value & QT2_SERIAL_MSR_DSR) ==
|
||||||
(msr_value & SERIAL_MSR_DSR))) ||
|
(msr_value & QT2_SERIAL_MSR_DSR))) ||
|
||||||
(arg & TIOCM_CD &&
|
(arg & TIOCM_CD &&
|
||||||
((prev_msr_value & SERIAL_MSR_CD) ==
|
((prev_msr_value & QT2_SERIAL_MSR_CD) ==
|
||||||
(msr_value & SERIAL_MSR_CD))) ||
|
(msr_value & QT2_SERIAL_MSR_CD))) ||
|
||||||
(arg & TIOCM_CTS &&
|
(arg & TIOCM_CTS &&
|
||||||
((prev_msr_value & SERIAL_MSR_CTS) ==
|
((prev_msr_value & QT2_SERIAL_MSR_CTS) ==
|
||||||
(msr_value & SERIAL_MSR_CTS)))) {
|
(msr_value & QT2_SERIAL_MSR_CTS)))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} /* end inifinite while */
|
} /* end inifinite while */
|
||||||
|
@ -952,6 +960,120 @@ static int qt2_ioctl(struct tty_struct *tty, struct file *file,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called when the user wishes to change the port settings using the termios
|
||||||
|
* userspace interface */
|
||||||
|
static void qt2_set_termios(struct tty_struct *tty,
|
||||||
|
struct usb_serial_port *port, struct ktermios *old_termios)
|
||||||
|
{
|
||||||
|
struct usb_serial *serial; /* parent serial device */
|
||||||
|
int baud, divisor, remainder;
|
||||||
|
unsigned char LCR_change_to = 0;
|
||||||
|
int status;
|
||||||
|
__u16 UartNumber;
|
||||||
|
|
||||||
|
dbg("%s(): port %d", __func__, port->number);
|
||||||
|
|
||||||
|
serial = port->serial;
|
||||||
|
|
||||||
|
UartNumber = port->number;
|
||||||
|
|
||||||
|
if (old_termios) {
|
||||||
|
if ((tty->termios->c_cflag == old_termios->c_cflag) &&
|
||||||
|
(RELEVANT_IFLAG(tty->termios->c_iflag) ==
|
||||||
|
RELEVANT_IFLAG(old_termios->c_iflag))) {
|
||||||
|
dbg("%s(): Nothing to change", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tty->termios->c_cflag) {
|
||||||
|
case CS5:
|
||||||
|
LCR_change_to |= QT2_SERIAL_5_DATA;
|
||||||
|
break;
|
||||||
|
case CS6:
|
||||||
|
LCR_change_to |= QT2_SERIAL_6_DATA;
|
||||||
|
break;
|
||||||
|
case CS7:
|
||||||
|
LCR_change_to |= QT2_SERIAL_7_DATA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case CS8:
|
||||||
|
LCR_change_to |= QT2_SERIAL_8_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parity stuff */
|
||||||
|
if (tty->termios->c_cflag & PARENB) {
|
||||||
|
if (tty->termios->c_cflag & PARODD)
|
||||||
|
LCR_change_to |= QT2_SERIAL_ODD_PARITY;
|
||||||
|
else
|
||||||
|
LCR_change_to |= QT2_SERIAL_EVEN_PARITY;
|
||||||
|
}
|
||||||
|
if (tty->termios->c_cflag & CSTOPB)
|
||||||
|
LCR_change_to |= QT2_SERIAL_TWO_STOPB;
|
||||||
|
else
|
||||||
|
LCR_change_to |= QT2_SERIAL_ONE_STOPB;
|
||||||
|
|
||||||
|
/* Thats the LCR stuff, go ahead and set it */
|
||||||
|
baud = tty_get_baud_rate(tty);
|
||||||
|
if (!baud) {
|
||||||
|
/* pick a default, any default... */
|
||||||
|
baud = 9600;
|
||||||
|
}
|
||||||
|
dbg("%s(): got baud = %d", __func__, baud);
|
||||||
|
|
||||||
|
divisor = QT2_MAX_BAUD_RATE / baud;
|
||||||
|
remainder = QT2_MAX_BAUD_RATE % baud;
|
||||||
|
/* Round to nearest divisor */
|
||||||
|
if (((remainder * 2) >= baud) && (baud != 110))
|
||||||
|
divisor++;
|
||||||
|
dbg("%s(): setting divisor = %d, QT2_MAX_BAUD_RATE = %d , LCR = 0x%x",
|
||||||
|
__func__, divisor, QT2_MAX_BAUD_RATE, LCR_change_to);
|
||||||
|
|
||||||
|
status = qt2_boxsetuart(serial, UartNumber, (unsigned short) divisor,
|
||||||
|
LCR_change_to);
|
||||||
|
if (status < 0) {
|
||||||
|
dbg("qt2_boxsetuart() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now determine flow control */
|
||||||
|
if (tty->termios->c_cflag & CRTSCTS) {
|
||||||
|
dbg("%s(): Enabling HW flow control port %d", __func__,
|
||||||
|
port->number);
|
||||||
|
/* Enable RTS/CTS flow control */
|
||||||
|
status = qt2_boxsethw_flowctl(serial, UartNumber, true);
|
||||||
|
if (status < 0) {
|
||||||
|
dbg("qt2_boxsethw_flowctl() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Disable RTS/CTS flow control */
|
||||||
|
dbg("%s(): disabling HW flow control port %d", __func__,
|
||||||
|
port->number);
|
||||||
|
status = qt2_boxsethw_flowctl(serial, UartNumber, false);
|
||||||
|
if (status < 0) {
|
||||||
|
dbg("qt2_boxsethw_flowctl failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* if we are implementing XON/XOFF, set the start and stop character
|
||||||
|
* in the device */
|
||||||
|
if (I_IXOFF(tty) || I_IXON(tty)) {
|
||||||
|
unsigned char stop_char = STOP_CHAR(tty);
|
||||||
|
unsigned char start_char = START_CHAR(tty);
|
||||||
|
status = qt2_boxsetsw_flowctl(serial, UartNumber, stop_char,
|
||||||
|
start_char);
|
||||||
|
if (status < 0)
|
||||||
|
dbg("qt2_boxsetsw_flowctl (enabled) failed");
|
||||||
|
} else {
|
||||||
|
/* disable SW flow control */
|
||||||
|
status = qt2_boxunsetsw_flowctl(serial, UartNumber);
|
||||||
|
if (status < 0)
|
||||||
|
dbg("qt2_boxunsetsw_flowctl (disabling) failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int qt2_tiocmget(struct tty_struct *tty, struct file *file)
|
static int qt2_tiocmget(struct tty_struct *tty, struct file *file)
|
||||||
{
|
{
|
||||||
struct usb_serial_port *port = tty->driver_data;
|
struct usb_serial_port *port = tty->driver_data;
|
||||||
|
@ -977,17 +1099,17 @@ static int qt2_tiocmget(struct tty_struct *tty, struct file *file)
|
||||||
QT2_MODEM_STATUS_REGISTER, &msr_value);
|
QT2_MODEM_STATUS_REGISTER, &msr_value);
|
||||||
}
|
}
|
||||||
if (status >= 0) {
|
if (status >= 0) {
|
||||||
result = ((mcr_value & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
|
result = ((mcr_value & QT2_SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
|
||||||
/*DTR set */
|
/*DTR set */
|
||||||
| ((mcr_value & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
|
| ((mcr_value & QT2_SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
|
||||||
/*RTS set */
|
/*RTS set */
|
||||||
| ((msr_value & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
|
| ((msr_value & QT2_SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
|
||||||
/* CTS set */
|
/* CTS set */
|
||||||
| ((msr_value & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
|
| ((msr_value & QT2_SERIAL_MSR_CD) ? TIOCM_CAR : 0)
|
||||||
/*Carrier detect set */
|
/*Carrier detect set */
|
||||||
| ((msr_value & SERIAL_MSR_RI) ? TIOCM_RI : 0)
|
| ((msr_value & QT2_SERIAL_MSR_RI) ? TIOCM_RI : 0)
|
||||||
/* Ring indicator set */
|
/* Ring indicator set */
|
||||||
| ((msr_value & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
|
| ((msr_value & QT2_SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
|
||||||
/* DSR set */
|
/* DSR set */
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1017,13 +1139,14 @@ static int qt2_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
|
|
||||||
/* Turn off RTS, DTR and loopback, then only turn on what was asked
|
/* Turn off RTS, DTR and loopback, then only turn on what was asked
|
||||||
* for */
|
* for */
|
||||||
mcr_value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
|
mcr_value &= ~(QT2_SERIAL_MCR_RTS | QT2_SERIAL_MCR_DTR |
|
||||||
|
QT2_SERIAL_MCR_LOOP);
|
||||||
if (set & TIOCM_RTS)
|
if (set & TIOCM_RTS)
|
||||||
mcr_value |= SERIAL_MCR_RTS;
|
mcr_value |= QT2_SERIAL_MCR_RTS;
|
||||||
if (set & TIOCM_DTR)
|
if (set & TIOCM_DTR)
|
||||||
mcr_value |= SERIAL_MCR_DTR;
|
mcr_value |= QT2_SERIAL_MCR_DTR;
|
||||||
if (set & TIOCM_LOOP)
|
if (set & TIOCM_LOOP)
|
||||||
mcr_value |= SERIAL_MCR_LOOP;
|
mcr_value |= QT2_SERIAL_MCR_LOOP;
|
||||||
|
|
||||||
status = qt2_box_set_register(port->serial, UartNumber,
|
status = qt2_box_set_register(port->serial, UartNumber,
|
||||||
QT2_MODEM_CONTROL_REGISTER, mcr_value);
|
QT2_MODEM_CONTROL_REGISTER, mcr_value);
|
||||||
|
@ -1162,7 +1285,7 @@ static int qt2_conf_uart(struct usb_serial *serial, unsigned short Uart_Number,
|
||||||
UartNumandLCR = (LCR << 8) + Uart_Number;
|
UartNumandLCR = (LCR << 8) + Uart_Number;
|
||||||
|
|
||||||
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||||
QT_GET_SET_UART, 0x40, divisor, UartNumandLCR,
|
QT2_GET_SET_UART, 0x40, divisor, UartNumandLCR,
|
||||||
NULL, 0, 300);
|
NULL, 0, 300);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1464,8 +1587,8 @@ static void qt2_process_line_status(struct usb_serial_port *port,
|
||||||
{
|
{
|
||||||
/* obtain the private structure for the port */
|
/* obtain the private structure for the port */
|
||||||
struct quatech2_port *port_extra = qt2_get_port_private(port);
|
struct quatech2_port *port_extra = qt2_get_port_private(port);
|
||||||
port_extra->shadowLSR = LineStatus & (SERIAL_LSR_OE | SERIAL_LSR_PE |
|
port_extra->shadowLSR = LineStatus & (QT2_SERIAL_LSR_OE |
|
||||||
SERIAL_LSR_FE | SERIAL_LSR_BI);
|
QT2_SERIAL_LSR_PE | QT2_SERIAL_LSR_FE | QT2_SERIAL_LSR_BI);
|
||||||
}
|
}
|
||||||
static void qt2_process_modem_status(struct usb_serial_port *port,
|
static void qt2_process_modem_status(struct usb_serial_port *port,
|
||||||
unsigned char ModemStatus)
|
unsigned char ModemStatus)
|
||||||
|
@ -1602,6 +1725,79 @@ static int qt2_box_flush(struct usb_serial *serial, unsigned char uart_number,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** qt2_boxsetuart - Issue a SET_UART vendor-spcific request on the default
|
||||||
|
* control pipe. If successful sets baud rate divisor and LCR value.
|
||||||
|
*/
|
||||||
|
static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
|
||||||
|
unsigned short default_divisor, unsigned char default_LCR)
|
||||||
|
{
|
||||||
|
unsigned short UartNumandLCR;
|
||||||
|
|
||||||
|
UartNumandLCR = (default_LCR << 8) + Uart_Number;
|
||||||
|
|
||||||
|
return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||||
|
QT2_GET_SET_UART, 0x40, default_divisor, UartNumandLCR,
|
||||||
|
NULL, 0, 300);
|
||||||
|
}
|
||||||
|
/** qt2_boxsethw_flowctl - Turn hardware (RTS/CTS) flow control on and off for
|
||||||
|
* a hardware UART.
|
||||||
|
*/
|
||||||
|
static int qt2_boxsethw_flowctl(struct usb_serial *serial,
|
||||||
|
unsigned int UartNumber, bool bSet)
|
||||||
|
{
|
||||||
|
__u8 MCR_Value = 0;
|
||||||
|
__u8 MSR_Value = 0;
|
||||||
|
__u16 MOUT_Value = 0;
|
||||||
|
|
||||||
|
if (bSet == true) {
|
||||||
|
MCR_Value = QT2_SERIAL_MCR_RTS;
|
||||||
|
/* flow control, box will clear RTS line to prevent remote
|
||||||
|
* device from transmitting more chars */
|
||||||
|
} else {
|
||||||
|
/* no flow control to remote device */
|
||||||
|
MCR_Value = 0;
|
||||||
|
}
|
||||||
|
MOUT_Value = MCR_Value << 8;
|
||||||
|
|
||||||
|
if (bSet == true) {
|
||||||
|
MSR_Value = QT2_SERIAL_MSR_CTS;
|
||||||
|
/* flow control on, box will inhibit tx data if CTS line is
|
||||||
|
* asserted */
|
||||||
|
} else {
|
||||||
|
/* Box will not inhibit tx data due to CTS line */
|
||||||
|
MSR_Value = 0;
|
||||||
|
}
|
||||||
|
MOUT_Value |= MSR_Value;
|
||||||
|
return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||||
|
QT2_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value, UartNumber,
|
||||||
|
NULL, 0, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** qt2_boxsetsw_flowctl - Turn software (XON/XOFF) flow control on for
|
||||||
|
* a hardware UART, and set the XON and XOFF characters.
|
||||||
|
*/
|
||||||
|
static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber,
|
||||||
|
unsigned char stop_char, unsigned char start_char)
|
||||||
|
{
|
||||||
|
__u16 nSWflowout;
|
||||||
|
|
||||||
|
nSWflowout = start_char << 8;
|
||||||
|
nSWflowout = (unsigned short)stop_char;
|
||||||
|
return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||||
|
QT2_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout, UartNumber,
|
||||||
|
NULL, 0, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** qt2_boxunsetsw_flowctl - Turn software (XON/XOFF) flow control off for
|
||||||
|
* a hardware UART.
|
||||||
|
*/
|
||||||
|
static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber)
|
||||||
|
{
|
||||||
|
return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||||
|
QT2_SW_FLOW_CONTROL_DISABLE, 0x40, 0, UartNumber, NULL,
|
||||||
|
0, 300);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* last things in file: stuff to register this driver into the generic
|
* last things in file: stuff to register this driver into the generic
|
||||||
* USB serial framework.
|
* USB serial framework.
|
||||||
|
@ -1625,8 +1821,8 @@ static struct usb_serial_driver quatech2_device = {
|
||||||
.unthrottle = qt_unthrottle,*/
|
.unthrottle = qt_unthrottle,*/
|
||||||
.calc_num_ports = qt2_calc_num_ports,
|
.calc_num_ports = qt2_calc_num_ports,
|
||||||
.ioctl = qt2_ioctl,
|
.ioctl = qt2_ioctl,
|
||||||
/*.set_termios = qt_set_termios,
|
.set_termios = qt2_set_termios,
|
||||||
.break_ctl = qt_break,*/
|
/*.break_ctl = qt_break,*/
|
||||||
.tiocmget = qt2_tiocmget,
|
.tiocmget = qt2_tiocmget,
|
||||||
.tiocmset = qt2_tiocmset,
|
.tiocmset = qt2_tiocmset,
|
||||||
.attach = qt2_attach,
|
.attach = qt2_attach,
|
||||||
|
|
Loading…
Reference in New Issue