From: Peter Hung <hpeter@gmail.com>
To: johan@kernel.org
Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, tom_tsai@fintek.com.tw,
peter_hong@fintek.com.tw,
Peter Hung <hpeter+linux_kernel@gmail.com>
Subject: [PATCH v4 6/7] usb: serial: implement MCR/MSR function for F81232
Date: Fri, 30 Jan 2015 14:13:40 +0800 [thread overview]
Message-ID: <1422598421-6236-6-git-send-email-hpeter+linux_kernel@gmail.com> (raw)
In-Reply-To: <1422598421-6236-1-git-send-email-hpeter+linux_kernel@gmail.com>
This patch implement relative MCR/MSR function, such like
tiocmget()/tiocmset()/dtr_rts().
The update_mctrl() replace set_control_lines() to do MCR control
so we clean-up the set_control_lines() function.
Signed-off-by: Peter Hung <hpeter+linux_kernel@gmail.com>
---
drivers/usb/serial/f81232.c | 105 ++++++++++++++++++++++++++++++++++----------
1 file changed, 83 insertions(+), 22 deletions(-)
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
index 248f40d..0ed7e36 100644
--- a/drivers/usb/serial/f81232.c
+++ b/drivers/usb/serial/f81232.c
@@ -38,11 +38,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
#define UART_STATE_TRANSIENT_MASK 0x74
#define UART_DCD 0x01
#define UART_DSR 0x02
-#define UART_BREAK_ERROR 0x04
#define UART_RING 0x08
-#define UART_FRAME_ERROR 0x10
-#define UART_PARITY_ERROR 0x20
-#define UART_OVERRUN_ERROR 0x40
#define UART_CTS 0x80
#define REGISTER_REQUEST 0xA0
@@ -55,6 +51,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
#define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS)
#define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS)
#define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS)
+#define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS)
#define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS)
struct f81232_private {
spinlock_t lock;
@@ -165,6 +162,62 @@ static void f81232_read_msr(struct f81232_private *priv)
dev_dbg(&dev->dev, "%s: %x\n", __func__, priv->line_status);
}
+
+static inline int update_mctrl(struct f81232_private *port_priv,
+ unsigned int set, unsigned int clear)
+{
+ struct usb_device *dev = port_priv->port->serial->dev;
+ u8 urb_value;
+ int status;
+ unsigned long flags;
+
+ if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) {
+ dev_dbg(&dev->dev, "%s fail - DTR|RTS %d\n",
+ __func__, __LINE__);
+ return 0; /* no change */
+ }
+
+ clear &= ~set; /* 'set' takes precedence over 'clear' */
+ urb_value = 8 | port_priv->line_control;
+
+ if (clear & TIOCM_DTR) {
+ urb_value &= ~UART_MCR_DTR;
+ dev_dbg(&dev->dev, "clear DTR\n");
+ }
+
+ if (clear & TIOCM_RTS) {
+ urb_value &= ~UART_MCR_RTS;
+ dev_dbg(&dev->dev, "clear RTS\n");
+ }
+
+ if (set & TIOCM_DTR) {
+ urb_value |= UART_MCR_DTR;
+ dev_dbg(&dev->dev, "set DTR\n");
+ }
+
+ if (set & TIOCM_RTS) {
+ urb_value |= UART_MCR_RTS;
+ dev_dbg(&dev->dev, "set RTS\n");
+ }
+
+ dev_dbg(&dev->dev, "%s n:%x o:%x\n", __func__, urb_value,
+ port_priv->line_control);
+
+ status = f81232_set_register(dev, MODEM_CONTROL_REGISTER, urb_value);
+
+ if (status < 0) {
+ dev_dbg(&dev->dev, "%s read MSR status < 0\n", __func__);
+ } else {
+ spin_lock_irqsave(&port_priv->lock, flags);
+ port_priv->line_control = urb_value;
+ spin_unlock_irqrestore(&port_priv->lock, flags);
+ }
+
+ f81232_read_msr(port_priv);
+
+ return status;
+}
+
static void f81232_update_line_status(struct usb_serial_port *port,
unsigned char *data,
unsigned int actual_length)
@@ -261,12 +314,6 @@ static void f81232_process_read_urb(struct urb *urb)
}
-static int set_control_lines(struct usb_device *dev, u8 value)
-{
- /* FIXME - Stubbed out for now */
- return 0;
-}
-
static void f81232_break_ctl(struct tty_struct *tty, int break_state)
{
/* FIXME - Stubbed out for now */
@@ -383,14 +430,35 @@ static void f81232_set_termios(struct tty_struct *tty,
static int f81232_tiocmget(struct tty_struct *tty)
{
- /* FIXME - Stubbed out for now */
- return 0;
+ int r;
+ struct usb_serial_port *port = tty->driver_data;
+ struct f81232_private *port_priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 mcr, msr;
+
+ spin_lock_irqsave(&port_priv->lock, flags);
+ mcr = port_priv->line_control;
+ msr = port_priv->line_status;
+ spin_unlock_irqrestore(&port_priv->lock, flags);
+
+ r = (mcr & UART_MCR_DTR ? TIOCM_DTR : 0) |
+ (mcr & UART_MCR_RTS ? TIOCM_RTS : 0) |
+ (msr & UART_MSR_CTS ? TIOCM_CTS : 0) |
+ (msr & UART_MSR_DCD ? TIOCM_CAR : 0) |
+ (msr & UART_MSR_RI ? TIOCM_RI : 0) |
+ (msr & UART_MSR_DSR ? TIOCM_DSR : 0);
+
+ return r;
}
static int f81232_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear)
{
- /* FIXME - Stubbed out for now */
+ struct usb_serial_port *port = tty->driver_data;
+ struct f81232_private *port_priv =
+ usb_get_serial_port_data(port);
+
+ update_mctrl(port_priv, set, clear);
return 0;
}
@@ -427,18 +495,11 @@ static void f81232_close(struct usb_serial_port *port)
static void f81232_dtr_rts(struct usb_serial_port *port, int on)
{
struct f81232_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
- u8 control;
- spin_lock_irqsave(&priv->lock, flags);
- /* Change DTR and RTS */
if (on)
- priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
+ update_mctrl(priv, TIOCM_DTR | TIOCM_RTS, 0);
else
- priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
- control = priv->line_control;
- spin_unlock_irqrestore(&priv->lock, flags);
- set_control_lines(port->serial->dev, control);
+ update_mctrl(priv, 0, TIOCM_DTR | TIOCM_RTS);
}
static int f81232_carrier_raised(struct usb_serial_port *port)
--
1.9.1
next prev parent reply other threads:[~2015-01-30 6:14 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-30 6:13 [PATCH v4 1/7] usb: serial: modify bulk-in/out size for F81232 Peter Hung
2015-01-30 6:13 ` [PATCH v4 2/7] usb: serial: modify author " Peter Hung
2015-02-04 11:31 ` Johan Hovold
2015-01-30 6:13 ` [PATCH v4 3/7] usb: serial: implement read IIR/MSR ep " Peter Hung
2015-02-04 12:41 ` Johan Hovold
2015-01-30 6:13 ` [PATCH v4 4/7] usb: serial: reimplement RX bulk-in " Peter Hung
2015-02-04 12:51 ` Johan Hovold
2015-01-30 6:13 ` [PATCH v4 5/7] usb: serial: implement set_termios " Peter Hung
2015-02-04 15:29 ` Johan Hovold
2015-01-30 6:13 ` Peter Hung [this message]
2015-02-04 15:55 ` [PATCH v4 6/7] usb: serial: implement MCR/MSR function " Johan Hovold
2015-01-30 6:13 ` [PATCH v4 7/7] usb: serial: modify ioctl TIOCGSERIAL " Peter Hung
2015-02-04 16:27 ` Johan Hovold
2015-02-04 11:23 ` [PATCH v4 1/7] usb: serial: modify bulk-in/out size " Johan Hovold
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1422598421-6236-6-git-send-email-hpeter+linux_kernel@gmail.com \
--to=hpeter@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=hpeter+linux_kernel@gmail.com \
--cc=johan@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=peter_hong@fintek.com.tw \
--cc=tom_tsai@fintek.com.tw \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.