// SPDX-License-Identifier: GPL-2.0+ /* * NI 16550 UART Driver * * The National Instruments (NI) 16550 is a UART that is compatible with the * TL16C550C and OX16C950B register interfaces, but has additional functions * for RS-485 transceiver control. This driver implements support for the * additional functionality on top of the standard serial8250 core. * * Copyright 2012-2023 National Instruments Corporation
*/
/* * If the PMR is not implemented, then by default NI UARTs are * connected to RS-485 transceivers
*/ if (pmr_cap == NI16550_PMR_NOT_IMPL) returnfalse;
if (pmr_cap == NI16550_PMR_CAP_DUAL) /* * If the port is dual-mode capable, then read the mode bit * to know the current mode
*/ return pmr_mode == NI16550_PMR_MODE_RS232; /* * If it is not dual-mode capable, then decide based on the * capability
*/ return pmr_cap == NI16550_PMR_CAP_RS232;
}
staticvoid ni16550_config_prescaler(struct uart_8250_port *up,
u8 prescaler)
{ /* * Page in the Enhanced Mode Registers * Sets EFR[4] for Enhanced Mode.
*/
u8 lcr_value;
u8 efr_value;
/* Page out the Enhanced Mode Registers */
serial_out(up, UART_LCR, lcr_value);
/* Set prescaler to CPR register. */
serial_out(up, UART_SCR, UART_CPR);
serial_out(up, UART_ICR, prescaler);
}
staticconststruct serial_rs485 ni16550_rs485_supported = {
.flags = SER_RS485_ENABLED | SER_RS485_MODE_RS422 | SER_RS485_RTS_ON_SEND |
SER_RS485_RTS_AFTER_SEND, /* * delay_rts_* and RX_DURING_TX are not supported. * * RTS_{ON,AFTER}_SEND are supported, but ignored; the transceiver * is connected in only one way and we don't need userspace to tell * us, but want to retain compatibility with applications that do.
*/
};
staticvoid ni16550_rs485_setup(struct uart_port *port)
{
port->rs485_config = ni16550_rs485_config;
port->rs485_supported = ni16550_rs485_supported; /* * The hardware comes up by default in 2-wire auto mode and we * set the flags to represent that
*/
port->rs485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
}
staticint ni16550_port_startup(struct uart_port *port)
{ int ret;
ret = serial8250_do_startup(port); if (ret) return ret;
/* * Very old implementations don't have the TFS or RFS registers * defined, so we may read all-0s or all-1s. For such devices, * assume a FIFO size of 128.
*/ static u8 ni16550_read_fifo_size(struct uart_8250_port *uart, int reg)
{
u8 value = serial_in(uart, reg);
/* * Hardware instantiation of FIFO sizes are held in registers.
*/
txfifosz = ni16550_read_fifo_size(uart, NI16550_TFS_OFFSET);
rxfifosz = ni16550_read_fifo_size(uart, NI16550_RFS_OFFSET);
/* * Declaration of the base clock frequency can come from one of: * - static declaration in this driver (for older ACPI IDs) * - a "clock-frequency" ACPI
*/
uart->port.uartclk = info->uartclk;
ret = uart_read_port_properties(&uart->port); if (ret) return ret;
if (!uart->port.uartclk) {
data->clk = devm_clk_get_enabled(dev, NULL); if (!IS_ERR(data->clk))
uart->port.uartclk = clk_get_rate(data->clk);
}
if (!uart->port.uartclk) return dev_err_probe(dev, -ENODEV, "unable to determine clock frequency!\n");
/* * The determination of whether or not this is an RS-485 or RS-232 port * can come from the PMR (if present), otherwise we're solely an RS-485 * port. * * This is a device-specific property, and there are old devices in the * field using "transceiver" as an ACPI property, so we have to check * for that as well.
*/ if (!device_property_read_string(dev, "transceiver", &portmode)) {
rs232_property = strncmp(portmode, "RS-232", 6) == 0;
dev_dbg(dev, "port is in %s mode (via PMR)\n",
rs232_property ? "RS-232" : "RS-485");
} else {
rs232_property = 0;
dev_dbg(dev, "port is fixed as RS-485\n");
}
if (!rs232_property) { /* * Neither the 'transceiver' property nor the PMR indicate * that this is an RS-232 port, so it must be an RS-485 one.
*/
ni16550_rs485_setup(&uart->port);
}
ret = serial8250_register_8250_port(uart); if (ret < 0) return ret;
data->line = ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.