dev/sc16is752: Add ioctl calls for modem controll.

This add ths following ioctl calls to the sc16is752 driver:
- TIOCMGET
- TIOCMSET
- TIOCMBIS
- TIOCMBIC
This commit is contained in:
Christian Mauderer
2018-05-03 08:54:02 +02:00
parent c8dcdf5438
commit c4f5cc5496
2 changed files with 96 additions and 1 deletions

View File

@@ -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)

View File

@@ -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);
}