diff options
Diffstat (limited to 'common/serial.c')
-rw-r--r-- | common/serial.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/common/serial.c b/common/serial.c new file mode 100644 index 0000000..f89bb0a --- /dev/null +++ b/common/serial.c @@ -0,0 +1,196 @@ +/* + * (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> + +#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; +#else +#error No default console +#endif +} +#endif + +static int serial_register(struct serial_device* dev) +{ + DECLARE_GLOBAL_DATA_PTR; + + 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 + + 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 (!serial_current) + { + struct serial_device *dev = default_serial_console(); + return dev->init(); + } + + return serial_current->init(); +} + +void serial_setbrg(void) +{ + if (!serial_current) + { + struct serial_device *dev = default_serial_console(); + dev->setbrg(); + return; + } + + serial_current->setbrg(); +} + +int serial_getc(void) +{ + if (!serial_current) + { + struct serial_device *dev = default_serial_console(); + return dev->getc(); + } + + return serial_current->getc(); +} + +int serial_tstc(void) +{ + if (!serial_current) + { + struct serial_device *dev = default_serial_console(); + return dev->tstc(); + } + + return serial_current->tstc(); +} + +void serial_putc(const char c) +{ + if (!serial_current) + { + struct serial_device *dev = default_serial_console(); + dev->putc(c); + return; + } + + serial_current->putc(c); +} + +void serial_puts(const char *s) +{ + if (!serial_current) + { + struct serial_device *dev = default_serial_console(); + dev->puts(s); + return; + } + + serial_current->puts(s); +} + +#endif /* CONFIG_SERIAL_MULTI */ |