Skip to content
Snippets Groups Projects
Commit ad1b81c8 authored by Simon Glass's avatar Simon Glass
Browse files

dm: serial: Support changing the baud rate


Implement this feature in the uclass so that the baudrate can be changed
with 'setenv baudrate <rate>'.

Signed-off-by: default avatarSimon Glass <sjg@chromium.org>
parent e87e0e79
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <environment.h>
#include <errno.h> #include <errno.h>
#include <fdtdec.h> #include <fdtdec.h>
#include <os.h> #include <os.h>
...@@ -22,6 +23,11 @@ DECLARE_GLOBAL_DATA_PTR; ...@@ -22,6 +23,11 @@ DECLARE_GLOBAL_DATA_PTR;
/* The currently-selected console serial device */ /* The currently-selected console serial device */
struct udevice *cur_dev __attribute__ ((section(".data"))); struct udevice *cur_dev __attribute__ ((section(".data")));
/*
* Table with supported baudrates (defined in config_xyz.h)
*/
static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
#ifndef CONFIG_SYS_MALLOC_F_LEN #ifndef CONFIG_SYS_MALLOC_F_LEN
#error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work" #error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work"
#endif #endif
...@@ -177,6 +183,67 @@ int serial_stub_tstc(struct stdio_dev *sdev) ...@@ -177,6 +183,67 @@ int serial_stub_tstc(struct stdio_dev *sdev)
return _serial_tstc(sdev->priv); return _serial_tstc(sdev->priv);
} }
/**
* on_baudrate() - Update the actual baudrate when the env var changes
*
* This will check for a valid baudrate and only apply it if valid.
*/
static int on_baudrate(const char *name, const char *value, enum env_op op,
int flags)
{
int i;
int baudrate;
switch (op) {
case env_op_create:
case env_op_overwrite:
/*
* Switch to new baudrate if new baudrate is supported
*/
baudrate = simple_strtoul(value, NULL, 10);
/* Not actually changing */
if (gd->baudrate == baudrate)
return 0;
for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
if (baudrate == baudrate_table[i])
break;
}
if (i == ARRAY_SIZE(baudrate_table)) {
if ((flags & H_FORCE) == 0)
printf("## Baudrate %d bps not supported\n",
baudrate);
return 1;
}
if ((flags & H_INTERACTIVE) != 0) {
printf("## Switch baudrate to %d bps and press ENTER ...\n",
baudrate);
udelay(50000);
}
gd->baudrate = baudrate;
serial_setbrg();
udelay(50000);
if ((flags & H_INTERACTIVE) != 0)
while (1) {
if (getc() == '\r')
break;
}
return 0;
case env_op_delete:
printf("## Baudrate may not be deleted\n");
return 1;
default:
return 0;
}
}
U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
static int serial_post_probe(struct udevice *dev) static int serial_post_probe(struct udevice *dev)
{ {
struct stdio_dev sdev; struct stdio_dev sdev;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment