Skip to content

Commit

Permalink
drivers: uart: ns16550: move from hard-coded to configurable
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
jenmwms authored and nashif committed Jan 21, 2020
1 parent 3a34db8 commit 68a2359
Showing 1 changed file with 56 additions and 12 deletions.
68 changes: 56 additions & 12 deletions drivers/serial/uart_ns16550.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ BUILD_ASSERT_MSG(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
/* convenience defines */

#define DEV_CFG(dev) \
((const struct uart_ns16550_device_config * const) \
((struct uart_ns16550_device_config * const) \
(dev)->config->config_info)
#define DEV_DATA(dev) \
((struct uart_ns16550_dev_data_t *)(dev)->driver_data)
Expand Down Expand Up @@ -315,7 +315,7 @@ static int uart_ns16550_configure(struct device *dev,
const struct uart_config *cfg)
{
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 */
u8_t mdc = 0U;
Expand All @@ -328,7 +328,7 @@ static int uart_ns16550_configure(struct device *dev,
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);
}
#endif
Expand All @@ -353,10 +353,53 @@ static int uart_ns16550_configure(struct device *dev,
}
#endif

set_baud_rate(dev, dev_data->uart_config.baudrate);
set_baud_rate(dev, cfg->baudrate);

/* Local structure to hold temporary values to pass to OUTBYTE() */
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;
}

/* 8 data bits, 1 stop bit, no parity, clear DLAB */
OUTBYTE(LCR(dev), LCR_CS8 | LCR_1_STB | LCR_PDIS);
/* 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;
if ((dev_data->options & UART_OPTION_AFCE) == UART_OPTION_AFCE) {
Expand Down Expand Up @@ -385,18 +428,19 @@ static int uart_ns16550_configure(struct device *dev,

irq_unlock(old_level);

return 0;
return 0;
};

static int uart_ns16550_config_get(struct device *dev, struct uart_config *cfg)
{
struct uart_ns16550_dev_data_t *data = DEV_DATA(dev);

cfg->baudrate = data->uart_config.baudrate;
cfg->parity = UART_CFG_PARITY_NONE; /* use uart_config_parity */
cfg->stop_bits = UART_CFG_STOP_BITS_1; /* use uart_config_stop_bits */
cfg->data_bits = UART_CFG_DATA_BITS_8; /* use uart_config_data_bits */
cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;/* use uart_config_flow_control */
cfg->parity = data->uart_config.parity;
cfg->stop_bits = data->uart_config.stop_bits;
cfg->data_bits = data->uart_config.data_bits;
cfg->flow_ctrl = data->uart_config.flow_ctrl;

return 0;
}

Expand All @@ -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)
{
uart_ns16550_configure(dev, &DEV_DATA(dev)->uart_config);
uart_ns16550_configure(dev, &DEV_DATA(dev)->uart_config);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
DEV_CFG(dev)->devconf.irq_config_func(dev);
Expand Down

0 comments on commit 68a2359

Please sign in to comment.