diff options
Diffstat (limited to 'common/serial.c')
-rwxr-xr-x | common/serial.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/common/serial.c b/common/serial.c new file mode 100755 index 0000000..2acbd08 --- /dev/null +++ b/common/serial.c @@ -0,0 +1,201 @@ +/* + * (C) Copyright 2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <serial.h> +#include <devices.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_SERIAL_MULTI) + +static struct serial_device *serial_devices = NULL; +static struct serial_device *serial_current = NULL; + +#ifndef CONFIG_LWMON +struct serial_device *default_serial_console (void) +{ +#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) + return &serial_smc_device; +#elif defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \ + || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) + return &serial_scc_device; +#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ + || defined(CONFIG_405EP) + return &serial0_device; +#else +#error No default console +#endif +} +#endif + +static int serial_register (struct serial_device *dev) +{ + dev->init += gd->reloc_off; + dev->setbrg += gd->reloc_off; + dev->getc += gd->reloc_off; + dev->tstc += gd->reloc_off; + dev->putc += gd->reloc_off; + dev->puts += gd->reloc_off; + + dev->next = serial_devices; + serial_devices = dev; + + return 0; +} + +void serial_initialize (void) +{ +#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) + serial_register (&serial_smc_device); +#endif +#if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \ + || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) + serial_register (&serial_scc_device); +#endif + +#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ + || defined(CONFIG_405EP) + serial_register(&serial0_device); + serial_register(&serial1_device); +#endif + + serial_assign (default_serial_console ()->name); +} + +void serial_devices_init (void) +{ + device_t dev; + struct serial_device *s = serial_devices; + + while (s) { + memset (&dev, 0, sizeof (dev)); + + strcpy (dev.name, s->name); + dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; + + dev.start = s->init; + dev.putc = s->putc; + dev.puts = s->puts; + dev.getc = s->getc; + dev.tstc = s->tstc; + + device_register (&dev); + + s = s->next; + } +} + +int serial_assign (char *name) +{ + struct serial_device *s; + + for (s = serial_devices; s; s = s->next) { + if (strcmp (s->name, name) == 0) { + serial_current = s; + return 0; + } + } + + return 1; +} + +void serial_reinit_all (void) +{ + struct serial_device *s; + + for (s = serial_devices; s; s = s->next) { + s->init (); + } +} + +int serial_init (void) +{ + if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { + struct serial_device *dev = default_serial_console (); + + return dev->init (); + } + + return serial_current->init (); +} + +void serial_setbrg (void) +{ + if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { + struct serial_device *dev = default_serial_console (); + + dev->setbrg (); + return; + } + + serial_current->setbrg (); +} + +int serial_getc (void) +{ + if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { + struct serial_device *dev = default_serial_console (); + + return dev->getc (); + } + + return serial_current->getc (); +} + +int serial_tstc (void) +{ + if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { + struct serial_device *dev = default_serial_console (); + + return dev->tstc (); + } + + return serial_current->tstc (); +} + +void serial_putc (const char c) +{ + if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { + struct serial_device *dev = default_serial_console (); + + dev->putc (c); + return; + } + + serial_current->putc (c); +} + +void serial_puts (const char *s) +{ + if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { + struct serial_device *dev = default_serial_console (); + + dev->puts (s); + return; + } + + serial_current->puts (s); +} + +#endif /* CONFIG_SERIAL_MULTI */ |