summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2018-05-03 08:54:02 +0200
committerChristian Mauderer <christian.mauderer@embedded-brains.de>2018-05-14 09:01:33 +0200
commitc4f5cc549641c2ff63223ee4203484538b4777e5 (patch)
tree0672cfc70de769e30c11b62222262a07acf22dce
parentsparc64 niagara, usiii: Remove -D options from cfg file and move to bspopts.h (diff)
downloadrtems-c4f5cc549641c2ff63223ee4203484538b4777e5.tar.bz2
dev/sc16is752: Add ioctl calls for modem controll.
This add ths following ioctl calls to the sc16is752 driver: - TIOCMGET - TIOCMSET - TIOCMBIS - TIOCMBIC
-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);
}