linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Joseph Pinkasfeld <jpinkasfeld@aldebaran-robotics.com>
To: akpm@linux-foundation.org
Cc: linux-serial@vger.kernel.org, linux-kernel@vgver.kernel.org
Subject: [PATCH 2/2] serial 16c950 : add preliminary support for 9-bit receive and transmit
Date: Wed, 18 Nov 2009 17:16:27 +0100	[thread overview]
Message-ID: <15447ab20911180816m45289649oa53e75a940e623f3@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0002-serial-16c950-add-preliminary-support-for-9-bit-rece.patch --]
[-- Type: text/x-patch, Size: 4570 bytes --]

From c706030ca2374fc3219010fcd479e0b5de36cabf Mon Sep 17 00:00:00 2001
From: pinkasfeld joseph <jpinkasfeld@aldebaran-robotics.com>
Date: Wed, 18 Nov 2009 16:35:16 +0100
Subject: [PATCH 2/2] serial 16c950 : add preliminary support for 9-bit receive and transmit
 2 bytes must be written or read for transmiting or receiving 9-bit data
 first byte LSB is ninth bit, second byte is normal data

Signed-off-by: pinkasfeld joseph <jpinkasfeld@aldebaran-robotics.com>
---
 drivers/serial/8250.c |   54 ++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 737b4c9..1b4143f 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -134,6 +134,7 @@ struct uart_8250_port {
 	unsigned short		bugs;		/* port bugs */
 	unsigned int		tx_loadsz;	/* transmit fifo load size */
 	unsigned char		acr;
+	unsigned char		nmr;
 	unsigned char		ier;
 	unsigned char		lcr;
 	unsigned char		mcr;
@@ -835,6 +836,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
 	 * recommended for new designs).
 	 */
 	up->acr = 0;
+	up->nmr = 0;
 	serial_out(up, UART_LCR, 0xBF);
 	serial_out(up, UART_EFR, UART_EFR_ECB);
 	serial_out(up, UART_LCR, 0x00);
@@ -1385,8 +1387,8 @@ static void
 receive_chars(struct uart_8250_port *up, unsigned int *status)
 {
 	struct tty_struct *tty = up->port.state->port.tty;
-	unsigned char ch, lsr = *status;
-	int max_count = 256;
+	unsigned char ch, ch9, lsr = *status;
+	int error_break = 0, max_count = 256;
 	char flag;
 
 	do {
@@ -1408,7 +1410,20 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
 		lsr |= up->lsr_saved_flags;
 		up->lsr_saved_flags = 0;
 
-		if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
+		/*
+		 * Due to sharing of bit 2 in LSR depending on 9 bits mode
+		 * bit 2 rise Parity Error or 9th bit read
+		 */
+		error_break = 0 ;
+		if (up->nmr & UART_NMR_9BENB) {
+			if (lsr & UART_LSR_NBM_BRK_ERROR_BITS)
+				error_break = 1;
+		} else {
+			if (lsr & UART_LSR_BRK_ERROR_BITS)
+				error_break = 1;
+		}
+
+		if (unlikely(error_break)) {
 			/*
 			 * For statistics only
 			 */
@@ -1423,7 +1438,8 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
 				 */
 				if (uart_handle_break(&up->port))
 					goto ignore_char;
-			} else if (lsr & UART_LSR_PE)
+			} else if ((lsr & UART_LSR_PE) &&
+				!(up->nmr & UART_NMR_9BENB))
 				up->port.icount.parity++;
 			else if (lsr & UART_LSR_FE)
 				up->port.icount.frame++;
@@ -1438,7 +1454,8 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
 			if (lsr & UART_LSR_BI) {
 				DEBUG_INTR("handling break....");
 				flag = TTY_BREAK;
-			} else if (lsr & UART_LSR_PE)
+			} else if ((lsr & UART_LSR_PE) &&
+				!(up->nmr & UART_NMR_9BENB))
 				flag = TTY_PARITY;
 			else if (lsr & UART_LSR_FE)
 				flag = TTY_FRAME;
@@ -1446,6 +1463,16 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
 		if (uart_handle_sysrq_char(&up->port, ch))
 			goto ignore_char;
 
+		/*
+		 * In 9bit mode Parity error is replace by 9th bit
+		 */
+		if (up->nmr & UART_NMR_9BENB) {
+			if (lsr & UART_LSR_9TH_BIT)
+				ch9 = 1;
+			else
+				ch9 = 0;
+			uart_insert_char(&up->port, lsr, UART_LSR_OE, ch9, flag);
+		}
 		uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
 
 ignore_char:
@@ -1479,6 +1506,13 @@ static void transmit_chars(struct uart_8250_port *up)
 
 	count = up->tx_loadsz;
 	do {
+		/* first byte contain 9th bit for 9 bit mode */
+		if ((up->nmr  & UART_NMR_9BENB)  && (count > 1) ){
+			serial_out(up, UART_SCR, 0x01 & xmit->buf[xmit->tail]);
+			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+			if (uart_circ_empty(xmit))
+				break;
+		}
 		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 		up->port.icount.tx++;
@@ -1956,6 +1990,7 @@ static int serial8250_startup(struct uart_port *port)
 	if (up->port.type == PORT_16C950) {
 		/* Wake up and initialize UART */
 		up->acr = 0;
+		up->nmr = 0;
 		serial_outp(up, UART_LCR, 0xBF);
 		serial_outp(up, UART_EFR, UART_EFR_ECB);
 		serial_outp(up, UART_IER, 0);
@@ -2412,6 +2447,15 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
 	/* Don't rewrite B0 */
 	if (tty_termios_baud_rate(termios))
 		tty_termios_encode_baud_rate(termios, baud, baud);
+
+	/*
+	 * 9-bit mode control flag on 16c950
+	 */
+	if (termios->c_cflag & CNBENB) {
+		up->nmr |= UART_NMR_9BENB;
+		serial_icr_write(up, UART_NMR, up->nmr);
+	}
+
 }
 
 static void
-- 
1.6.5.2


                 reply	other threads:[~2009-11-18 16:16 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=15447ab20911180816m45289649oa53e75a940e623f3@mail.gmail.com \
    --to=jpinkasfeld@aldebaran-robotics.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vgver.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).