From c4f5cc549641c2ff63223ee4203484538b4777e5 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Thu, 3 May 2018 08:54:02 +0200 Subject: dev/sc16is752: Add ioctl calls for modem controll. 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); } -- cgit v1.2.3