[PATCH] dev/sc16is752: Add ioctl calls for modem controll.

Christian Mauderer christian.mauderer at embedded-brains.de
Thu May 3 06:54:02 UTC 2018


This add ths following ioctl calls to the sc16is752 driver:
- TIOCMGET
- TIOCMSET
- TIOCMBIS
- TIOCMBIC
---
 cpukit/dev/serial/sc16is752-regs.h | 18 ++++++++-
 cpukit/dev/serial/sc16is752.c      | 79 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/cpukit/dev/serial/sc16is752-regs.h b/cpukit/dev/serial/sc16is752-regs.h
index 847874baab..21d425a118 100644
--- a/cpukit/dev/serial/sc16is752-regs.h
+++ b/cpukit/dev/serial/sc16is752-regs.h
@@ -99,7 +99,23 @@ extern "C" {
 #define LSR_ERROR_BITS (7u << 2)
 
 /* MCR */
-#define MCR_PRESCALE_NEEDED (1u << 0)
+#define MCR_DTR             (1u << 0)
+#define MCR_RTS             (1u << 1)
+#define MCR_TCR_TLR         (1u << 2)
+#define MCR_LOOPBACK        (1u << 4)
+#define MCR_XON_ANY         (1u << 5)
+#define MCR_IRDA_ENABLE     (1u << 6)
+#define MCR_PRESCALE_NEEDED (1u << 7)
+
+/* MSR */
+#define MSR_dCTS (1u << 0)
+#define MSR_dDSR (1u << 1)
+#define MSR_dRI  (1u << 2)
+#define MSR_dCD  (1u << 3)
+#define MSR_CTS  (1u << 4)
+#define MSR_DSR  (1u << 5)
+#define MSR_RI   (1u << 6)
+#define MSR_CD   (1u << 7)
 
 /* EFR */
 #define EFR_ENHANCED_FUNC_ENABLE (1u << 4)
diff --git a/cpukit/dev/serial/sc16is752.c b/cpukit/dev/serial/sc16is752.c
index 39e5df2ae7..ac88c8389f 100644
--- a/cpukit/dev/serial/sc16is752.c
+++ b/cpukit/dev/serial/sc16is752.c
@@ -277,6 +277,73 @@ static void sc16is752_write(
   }
 }
 
+static void sc16is752_get_modem_bits(sc16is752_context *ctx, int *bits)
+{
+  *bits = 0;
+  uint8_t msr;
+  uint8_t mcr;
+
+  read_reg(ctx, SC16IS752_MSR, &msr, 1);
+  read_reg(ctx, SC16IS752_MCR, &mcr, 1);
+
+  if (msr & MSR_CTS) {
+    *bits |= TIOCM_CTS;
+  }
+  if (msr & MSR_DSR) {
+    *bits |= TIOCM_DSR;
+  }
+  if (msr & MSR_RI) {
+    *bits |= TIOCM_RI;
+  }
+  if (msr & MSR_CD) {
+    *bits |= TIOCM_CD;
+  }
+  if ((mcr & MCR_DTR) == 0) {
+    *bits |= TIOCM_DTR;
+  }
+  if ((mcr & MCR_RTS) == 0) {
+    *bits |= TIOCM_RTS;
+  }
+}
+
+static void sc16is752_set_modem_bits(
+  sc16is752_context *ctx, int *bits, int set, int clear
+)
+{
+  uint8_t mcr;
+
+  read_reg(ctx, SC16IS752_MCR, &mcr, 1);
+
+  if (bits != NULL) {
+    if ((*bits & TIOCM_DTR) == 0) {
+      mcr |= MCR_DTR;
+    } else {
+      mcr &= ~MCR_DTR;
+    }
+
+    if ((*bits & TIOCM_RTS) == 0) {
+      mcr |= MCR_RTS;
+    } else {
+      mcr &= ~MCR_RTS;
+    }
+  }
+
+  if ((set & TIOCM_DTR) != 0) {
+    mcr &= ~MCR_DTR;
+  }
+  if ((set & TIOCM_RTS) != 0) {
+    mcr &= ~MCR_RTS;
+  }
+  if ((clear & TIOCM_DTR) != 0) {
+    mcr |= MCR_DTR;
+  }
+  if ((clear & TIOCM_RTS) != 0) {
+    mcr |= MCR_RTS;
+  }
+
+  write_reg(ctx, SC16IS752_MCR, &mcr, 1);
+}
+
 static int sc16is752_ioctl(
   rtems_termios_device_context *base,
   ioctl_command_t               request,
@@ -312,6 +379,18 @@ static int sc16is752_ioctl(
     case SC16IS752_GET_IOSTATE:
       read_reg(ctx, SC16IS752_IOSTATE, (uint8_t *)buffer, 1);
       break;
+    case TIOCMGET:
+      sc16is752_get_modem_bits(ctx, (int *)buffer);
+      break;
+    case TIOCMSET:
+      sc16is752_set_modem_bits(ctx, (int *)buffer, 0, 0);
+      break;
+    case TIOCMBIS:
+      sc16is752_set_modem_bits(ctx, NULL, *(int *)buffer, 0);
+      break;
+    case TIOCMBIC:
+      sc16is752_set_modem_bits(ctx, NULL, 0, *(int *)buffer);
+      break;
     default:
       rtems_set_errno_and_return_minus_one(EINVAL);
   }
-- 
2.13.6



More information about the devel mailing list