drivers: serial: Improve BFLB UART driver: add runtime configuration
This adds the ability to do runtime configuration of the BFLB
UART driver.
Signed-off-by: Camille BAUD <mail@massdriver.space>
diff --git a/drivers/serial/uart_bflb.c b/drivers/serial/uart_bflb.c
index 10e1403..9f7abff 100644
--- a/drivers/serial/uart_bflb.c
+++ b/drivers/serial/uart_bflb.c
@@ -33,13 +33,7 @@
struct bflb_config {
const struct pinctrl_dev_config *pincfg;
- uint32_t baudrate;
- uint8_t direction;
- uint8_t data_bits;
- uint8_t stop_bits;
- uint8_t parity;
uint8_t bit_order;
- uint8_t flow_ctrl;
uint8_t tx_fifo_threshold;
uint8_t rx_fifo_threshold;
uint32_t base_reg;
@@ -49,6 +43,7 @@
};
struct bflb_data {
+ struct uart_config uart_cfg;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_irq_callback_user_data_t user_cb;
void *user_data;
@@ -294,12 +289,13 @@
static int uart_bflb_configure(const struct device *dev)
{
const struct bflb_config *cfg = dev->config;
+ struct bflb_data *const data = dev->data;
uint32_t tx_cfg = 0;
uint32_t rx_cfg = 0;
uint32_t divider = 0;
uint32_t tmp = 0;
- divider = (uart_bflb_get_clock() * 10 / cfg->baudrate + 5) / 10;
+ divider = (uart_bflb_get_clock() * 10 / data->uart_cfg.baudrate + 5) / 10;
if (divider >= 0xFFFF) {
divider = 0xFFFF - 1;
}
@@ -314,7 +310,7 @@
tx_cfg = sys_read32(cfg->base_reg + UART_UTX_CONFIG_OFFSET);
rx_cfg = sys_read32(cfg->base_reg + UART_URX_CONFIG_OFFSET);
- switch (cfg->parity) {
+ switch (data->uart_cfg.parity) {
case UART_PARITY_NONE:
tx_cfg &= ~UART_CR_UTX_PRT_EN;
rx_cfg &= ~UART_CR_URX_PRT_EN;
@@ -337,16 +333,16 @@
/* Configure data bits */
tx_cfg &= ~UART_CR_UTX_BIT_CNT_D_MASK;
- tx_cfg |= (cfg->data_bits + 4) << UART_CR_UTX_BIT_CNT_D_SHIFT;
+ tx_cfg |= (data->uart_cfg.data_bits + 4) << UART_CR_UTX_BIT_CNT_D_SHIFT;
rx_cfg &= ~UART_CR_URX_BIT_CNT_D_MASK;
- rx_cfg |= (cfg->data_bits + 4) << UART_CR_URX_BIT_CNT_D_SHIFT;
+ rx_cfg |= (data->uart_cfg.data_bits + 4) << UART_CR_URX_BIT_CNT_D_SHIFT;
/* Configure tx stop bits */
tx_cfg &= ~UART_CR_UTX_BIT_CNT_P_MASK;
- tx_cfg |= cfg->stop_bits << UART_CR_UTX_BIT_CNT_P_SHIFT;
+ tx_cfg |= data->uart_cfg.stop_bits << UART_CR_UTX_BIT_CNT_P_SHIFT;
/* Configure tx cts flow control function */
- if (cfg->flow_ctrl & UART_FLOWCTRL_CTS) {
+ if (data->uart_cfg.flow_ctrl & UART_FLOWCTRL_CTS) {
tx_cfg |= UART_CR_UTX_CTS_EN;
} else {
tx_cfg &= ~UART_CR_UTX_CTS_EN;
@@ -401,6 +397,38 @@
return 0;
}
+#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
+
+static int uart_bflb_runtime_configure(const struct device *dev,
+ const struct uart_config *cfg)
+{
+ struct bflb_data *data = dev->data;
+ int ret;
+
+ data->uart_cfg = *cfg;
+
+ ret = uart_bflb_configure(dev);
+ if (ret < 0) {
+ return ret;
+ }
+
+ uart_bflb_enabled(dev, 1);
+
+ return 0;
+}
+
+static int uart_bflb_runtime_config_get(const struct device *dev,
+ struct uart_config *cfg)
+{
+ struct bflb_data *data = dev->data;
+
+ *cfg = data->uart_cfg;
+
+ return 0;
+}
+
+#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
+
static int uart_bflb_init(const struct device *dev)
{
const struct bflb_config *cfg = dev->config;
@@ -519,6 +547,10 @@
static DEVICE_API(uart, uart_bflb_driver_api) = {
.poll_in = uart_bflb_poll_in,
.poll_out = uart_bflb_poll_out,
+#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
+ .configure = uart_bflb_runtime_configure,
+ .config_get = uart_bflb_runtime_config_get,
+#endif
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.err_check = uart_bflb_err_check,
.fifo_fill = uart_bflb_fifo_fill,
@@ -564,18 +596,22 @@
PINCTRL_DT_INST_DEFINE(instance); \
PM_DEVICE_DT_INST_DEFINE(instance, uart_bflb_pm_control); \
BFLB_UART_IRQ_HANDLER_DECL(instance) \
- static struct bflb_data uart##instance##_bflb_data; \
+ static struct bflb_data uart##instance##_bflb_data = { \
+ .uart_cfg = { \
+ .baudrate = DT_INST_PROP(instance, current_speed), \
+ .parity = UART_CFG_PARITY_NONE, \
+ .stop_bits = UART_CFG_STOP_BITS_1, \
+ .data_bits = UART_CFG_DATA_BITS_8, \
+ .flow_ctrl = DT_INST_PROP(instance, hw_flow_control) \
+ ? UART_CFG_FLOW_CTRL_RTS_CTS \
+ : UART_CFG_FLOW_CTRL_NONE, \
+ }, \
+ }; \
static const struct bflb_config uart##instance##_bflb_config = { \
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(instance), \
.base_reg = DT_INST_REG_ADDR(instance), \
\
- .baudrate = DT_INST_PROP(instance, current_speed), \
- .data_bits = UART_DATA_BITS_8, \
- .stop_bits = UART_STOP_BITS_1, \
- .parity = UART_PARITY_NONE, \
.bit_order = UART_MSB_FIRST, \
- .flow_ctrl = UART_FLOWCTRL_NONE, \
- /* overflow interrupt threshold, size is 32 bytes*/ \
.tx_fifo_threshold = 8, \
.rx_fifo_threshold = 0, \
BFLB_UART_IRQ_HANDLER_FUNC(instance) \