drivers: uart: ns16550: move from hard-coded to configurable

The NS16550 UART driver is currently hard-coded as 8-n-1
with no flow control. The baud rate is set by what is in DTS.
This commit moves away from hard-coded and strictly DTS to
configurable using the UART configure API. Requires commit #bcb807.

Signed-off-by: Jennifer Williams <jennifer.m.williams@intel.com>
This commit is contained in:
Jennifer Williams 2020-01-10 19:12:48 -08:00 committed by Anas Nashif
commit 68a235932f

View file

@ -199,7 +199,7 @@ BUILD_ASSERT_MSG(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
/* convenience defines */ /* convenience defines */
#define DEV_CFG(dev) \ #define DEV_CFG(dev) \
((const struct uart_ns16550_device_config * const) \ ((struct uart_ns16550_device_config * const) \
(dev)->config->config_info) (dev)->config->config_info)
#define DEV_DATA(dev) \ #define DEV_DATA(dev) \
((struct uart_ns16550_dev_data_t *)(dev)->driver_data) ((struct uart_ns16550_dev_data_t *)(dev)->driver_data)
@ -315,7 +315,7 @@ static int uart_ns16550_configure(struct device *dev,
const struct uart_config *cfg) const struct uart_config *cfg)
{ {
struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev);
const struct uart_ns16550_device_config * const dev_cfg = DEV_CFG(dev); struct uart_ns16550_device_config * const dev_cfg = DEV_CFG(dev);
unsigned int old_level; /* old interrupt lock level */ unsigned int old_level; /* old interrupt lock level */
u8_t mdc = 0U; u8_t mdc = 0U;
@ -328,7 +328,7 @@ static int uart_ns16550_configure(struct device *dev,
return -EINVAL; return -EINVAL;
} }
dev_data->port = pcie_get_mbar(dev_cfg->pcie_bdf, 0); dev_cfg->devconf.port = pcie_get_mbar(dev_cfg->pcie_bdf, 0);
pcie_set_cmd(dev_cfg->pcie_bdf, PCIE_CONF_CMDSTAT_MEM, true); pcie_set_cmd(dev_cfg->pcie_bdf, PCIE_CONF_CMDSTAT_MEM, true);
} }
#endif #endif
@ -353,10 +353,53 @@ static int uart_ns16550_configure(struct device *dev,
} }
#endif #endif
set_baud_rate(dev, dev_data->uart_config.baudrate); set_baud_rate(dev, cfg->baudrate);
/* 8 data bits, 1 stop bit, no parity, clear DLAB */ /* Local structure to hold temporary values to pass to OUTBYTE() */
OUTBYTE(LCR(dev), LCR_CS8 | LCR_1_STB | LCR_PDIS); struct uart_config uart_cfg;
switch (cfg->data_bits) {
case UART_CFG_DATA_BITS_5:
uart_cfg.data_bits = LCR_CS5;
break;
case UART_CFG_DATA_BITS_6:
uart_cfg.data_bits = LCR_CS6;
break;
case UART_CFG_DATA_BITS_7:
uart_cfg.data_bits = LCR_CS7;
break;
case UART_CFG_DATA_BITS_8:
uart_cfg.data_bits = LCR_CS8;
break;
default:
return -ENOTSUP;
}
switch (cfg->stop_bits) {
case UART_CFG_STOP_BITS_1:
uart_cfg.stop_bits = LCR_1_STB;
break;
case UART_CFG_STOP_BITS_2:
uart_cfg.stop_bits = LCR_2_STB;
break;
default:
return -ENOTSUP;
}
switch (cfg->parity) {
case UART_CFG_PARITY_NONE:
uart_cfg.parity = LCR_PDIS;
break;
case UART_CFG_PARITY_EVEN:
uart_cfg.parity = LCR_EPS;
break;
default:
return -ENOTSUP;
}
/* data bits, stop bits, parity, clear DLAB */
OUTBYTE(LCR(dev),
uart_cfg.data_bits | uart_cfg.stop_bits | uart_cfg.parity);
mdc = MCR_OUT2 | MCR_RTS | MCR_DTR; mdc = MCR_OUT2 | MCR_RTS | MCR_DTR;
if ((dev_data->options & UART_OPTION_AFCE) == UART_OPTION_AFCE) { if ((dev_data->options & UART_OPTION_AFCE) == UART_OPTION_AFCE) {
@ -385,7 +428,7 @@ static int uart_ns16550_configure(struct device *dev,
irq_unlock(old_level); irq_unlock(old_level);
return 0; return 0;
}; };
static int uart_ns16550_config_get(struct device *dev, struct uart_config *cfg) static int uart_ns16550_config_get(struct device *dev, struct uart_config *cfg)
@ -393,10 +436,11 @@ static int uart_ns16550_config_get(struct device *dev, struct uart_config *cfg)
struct uart_ns16550_dev_data_t *data = DEV_DATA(dev); struct uart_ns16550_dev_data_t *data = DEV_DATA(dev);
cfg->baudrate = data->uart_config.baudrate; cfg->baudrate = data->uart_config.baudrate;
cfg->parity = UART_CFG_PARITY_NONE; /* use uart_config_parity */ cfg->parity = data->uart_config.parity;
cfg->stop_bits = UART_CFG_STOP_BITS_1; /* use uart_config_stop_bits */ cfg->stop_bits = data->uart_config.stop_bits;
cfg->data_bits = UART_CFG_DATA_BITS_8; /* use uart_config_data_bits */ cfg->data_bits = data->uart_config.data_bits;
cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;/* use uart_config_flow_control */ cfg->flow_ctrl = data->uart_config.flow_ctrl;
return 0; return 0;
} }
@ -411,7 +455,7 @@ static int uart_ns16550_config_get(struct device *dev, struct uart_config *cfg)
*/ */
static int uart_ns16550_init(struct device *dev) static int uart_ns16550_init(struct device *dev)
{ {
uart_ns16550_configure(dev, &DEV_DATA(dev)->uart_config); uart_ns16550_configure(dev, &DEV_DATA(dev)->uart_config);
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN
DEV_CFG(dev)->devconf.irq_config_func(dev); DEV_CFG(dev)->devconf.irq_config_func(dev);