From 29d7fb35e09b59b3f694d610c689ae6ee816d6e0 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Tue, 26 Jun 2018 11:55:57 +0530 Subject: [PATCH] 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 Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/gadget/function/f_cdev.c | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index d541892a129c..31ec75fed944 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -353,6 +353,23 @@ static inline struct f_cdev *cser_to_port(struct cserial *cser) 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; @@ -1362,6 +1379,9 @@ static int f_cdev_tiocmget(struct f_cdev *port) if (cser->serial_state & TIOCM_RI) result |= TIOCM_RI; + + if (cser->serial_state & TIOCM_DSR) + result |= TIOCM_DSR; return result; } @@ -1402,6 +1422,12 @@ static int f_cdev_tiocmset(struct f_cdev *port, } } + if (set & TIOCM_DSR) + cser->serial_state |= TIOCM_DSR; + + if (clear & TIOCM_DSR) + cser->serial_state &= ~TIOCM_DSR; + return status; } @@ -1452,7 +1478,9 @@ static void usb_cser_notify_modem(void *fport, int ctrl_bits) { int temp; struct f_cdev *port = fport; + struct cserial *cser; + cser = &port->port_usb; if (!port) { pr_err("port is null\n"); return; @@ -1468,6 +1496,17 @@ static void usb_cser_notify_modem(void *fport, int ctrl_bits) 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); }