1/* 2 * (C) Copyright 2004 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24#include <common.h> 25#include <serial.h> 26#include <devices.h> 27 28DECLARE_GLOBAL_DATA_PTR; 29 30static struct serial_device *serial_devices = NULL; 31static struct serial_device *serial_current = NULL; 32 33#if !defined(CONFIG_LWMON) && !defined(CONFIG_PXA27X) 34struct serial_device *__default_serial_console (void) 35{ 36#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) 37 return &serial_smc_device; 38#elif defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \ 39 || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) 40 return &serial_scc_device; 41#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ 42 || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \ 43 || defined(CONFIG_MPC5xxx) 44#if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL) 45#if (CONFIG_CONS_INDEX==1) 46 return &eserial1_device; 47#elif (CONFIG_CONS_INDEX==2) 48 return &eserial2_device; 49#elif (CONFIG_CONS_INDEX==3) 50 return &eserial3_device; 51#elif (CONFIG_CONS_INDEX==4) 52 return &eserial4_device; 53#else 54#error "Bad CONFIG_CONS_INDEX." 55#endif 56#elif defined(CONFIG_UART1_CONSOLE) 57 return &serial1_device; 58#else 59 return &serial0_device; 60#endif 61#elif defined(CONFIG_S3C2410) 62#if defined(CONFIG_SERIAL1) 63 return &s3c24xx_serial0_device; 64#elif defined(CONFIG_SERIAL2) 65 return &s3c24xx_serial1_device; 66#elif defined(CONFIG_SERIAL3) 67 return &s3c24xx_serial2_device; 68#else 69#error "CONFIG_SERIAL? missing." 70#endif 71#else 72#error No default console 73#endif 74} 75 76struct serial_device *default_serial_console(void) __attribute__((weak, alias("__default_serial_console"))); 77#endif 78 79int serial_register (struct serial_device *dev) 80{ 81 dev->init += gd->reloc_off; 82 dev->setbrg += gd->reloc_off; 83 dev->getc += gd->reloc_off; 84 dev->tstc += gd->reloc_off; 85 dev->putc += gd->reloc_off; 86 dev->puts += gd->reloc_off; 87 88 dev->next = serial_devices; 89 serial_devices = dev; 90 91 return 0; 92} 93 94void serial_initialize (void) 95{ 96#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) 97 serial_register (&serial_smc_device); 98#endif 99#if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \ 100 || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) 101 serial_register (&serial_scc_device); 102#endif 103 104#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ 105 || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \ 106 || defined(CONFIG_MPC5xxx) 107 serial_register(&serial0_device); 108 serial_register(&serial1_device); 109#endif 110 111#if defined(CONFIG_SYS_NS16550_SERIAL) 112#if defined(CONFIG_SYS_NS16550_COM1) 113 serial_register(&eserial1_device); 114#endif 115#if defined(CONFIG_SYS_NS16550_COM2) 116 serial_register(&eserial2_device); 117#endif 118#if defined(CONFIG_SYS_NS16550_COM3) 119 serial_register(&eserial3_device); 120#endif 121#if defined(CONFIG_SYS_NS16550_COM4) 122 serial_register(&eserial4_device); 123#endif 124#endif /* CONFIG_SYS_NS16550_SERIAL */ 125#if defined (CONFIG_FFUART) 126 serial_register(&serial_ffuart_device); 127#endif 128#if defined (CONFIG_BTUART) 129 serial_register(&serial_btuart_device); 130#endif 131#if defined (CONFIG_STUART) 132 serial_register(&serial_stuart_device); 133#endif 134#if defined(CONFIG_S3C2410) 135 serial_register(&s3c24xx_serial0_device); 136 serial_register(&s3c24xx_serial1_device); 137 serial_register(&s3c24xx_serial2_device); 138#endif 139 serial_assign (default_serial_console ()->name); 140} 141 142void serial_devices_init (void) 143{ 144 device_t dev; 145 struct serial_device *s = serial_devices; 146 147 while (s) { 148 memset (&dev, 0, sizeof (dev)); 149 150 strcpy (dev.name, s->name); 151 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 152 153 dev.start = s->init; 154 dev.putc = s->putc; 155 dev.puts = s->puts; 156 dev.getc = s->getc; 157 dev.tstc = s->tstc; 158 159 device_register (&dev); 160 161 s = s->next; 162 } 163} 164 165int serial_assign (char *name) 166{ 167 struct serial_device *s; 168 169 for (s = serial_devices; s; s = s->next) { 170 if (strcmp (s->name, name) == 0) { 171 serial_current = s; 172 return 0; 173 } 174 } 175 176 return 1; 177} 178 179void serial_reinit_all (void) 180{ 181 struct serial_device *s; 182 183 for (s = serial_devices; s; s = s->next) { 184 s->init (); 185 } 186} 187 188int serial_init (void) 189{ 190 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { 191 struct serial_device *dev = default_serial_console (); 192 193 return dev->init (); 194 } 195 196 return serial_current->init (); 197} 198 199void serial_setbrg (void) 200{ 201 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { 202 struct serial_device *dev = default_serial_console (); 203 204 dev->setbrg (); 205 return; 206 } 207 208 serial_current->setbrg (); 209} 210 211int serial_getc (void) 212{ 213 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { 214 struct serial_device *dev = default_serial_console (); 215 216 return dev->getc (); 217 } 218 219 return serial_current->getc (); 220} 221 222int serial_tstc (void) 223{ 224 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { 225 struct serial_device *dev = default_serial_console (); 226 227 return dev->tstc (); 228 } 229 230 return serial_current->tstc (); 231} 232 233void serial_putc (const char c) 234{ 235 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { 236 struct serial_device *dev = default_serial_console (); 237 238 dev->putc (c); 239 return; 240 } 241 242 serial_current->putc (c); 243} 244 245void serial_puts (const char *s) 246{ 247 if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { 248 struct serial_device *dev = default_serial_console (); 249 250 dev->puts (s); 251 return; 252 } 253 254 serial_current->puts (s); 255} 256