usb: gadget: Send DSR linestate on DTR high from host
When the host PC sends a DTR high during DUN call,
it expects to get a DSR signal from the modem in reply.
Add necessary support for that.
Change-Id: If46c4b75fa6210c2b15cd2880bc93461fa3a4e89
Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c
index a7166e2..c246c0f 100644
--- a/drivers/usb/gadget/function/f_cdev.c
+++ b/drivers/usb/gadget/function/f_cdev.c
@@ -349,6 +349,23 @@
return container_of(cser, struct f_cdev, port_usb);
}
+static unsigned int convert_uart_sigs_to_acm(unsigned int uart_sig)
+{
+ unsigned int acm_sig = 0;
+
+ /* should this needs to be in calling functions ??? */
+ uart_sig &= (TIOCM_RI | TIOCM_CD | TIOCM_DSR);
+
+ if (uart_sig & TIOCM_RI)
+ acm_sig |= ACM_CTRL_RI;
+ if (uart_sig & TIOCM_CD)
+ acm_sig |= ACM_CTRL_DCD;
+ if (uart_sig & TIOCM_DSR)
+ acm_sig |= ACM_CTRL_DSR;
+
+ return acm_sig;
+}
+
static unsigned int convert_acm_sigs_to_uart(unsigned int acm_sig)
{
unsigned int uart_sig = 0;
@@ -1333,6 +1350,9 @@
if (cser->serial_state & TIOCM_RI)
result |= TIOCM_RI;
+
+ if (cser->serial_state & TIOCM_DSR)
+ result |= TIOCM_DSR;
return result;
}
@@ -1373,6 +1393,12 @@
}
}
+ if (set & TIOCM_DSR)
+ cser->serial_state |= TIOCM_DSR;
+
+ if (clear & TIOCM_DSR)
+ cser->serial_state &= ~TIOCM_DSR;
+
return status;
}
@@ -1423,7 +1449,9 @@
{
int temp;
struct f_cdev *port = fport;
+ struct cserial *cser;
+ cser = &port->port_usb;
if (!port) {
pr_err("port is null\n");
return;
@@ -1439,6 +1467,17 @@
port->cbits_to_modem = temp;
port->cbits_updated = true;
+ /* if DTR is high, update latest modem info to laptop */
+ if (port->cbits_to_modem & TIOCM_DTR) {
+ unsigned int result;
+ unsigned int cbits_to_laptop;
+
+ result = f_cdev_tiocmget(port);
+ cbits_to_laptop = convert_uart_sigs_to_acm(result);
+ if (cser->send_modem_ctrl_bits)
+ cser->send_modem_ctrl_bits(cser, cbits_to_laptop);
+ }
+
wake_up(&port->read_wq);
}