summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpukit/dev/serial/sc16is752-regs.h18
-rw-r--r--cpukit/dev/serial/sc16is752.c79
2 files changed, 96 insertions, 1 deletions
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);
}