serial.c 6.8 KB
Newer Older
W
wdenk 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * (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>
26
#include <stdio_dev.h>
W
wdenk 已提交
27

28 29
DECLARE_GLOBAL_DATA_PTR;

W
wdenk 已提交
30 31 32
static struct serial_device *serial_devices = NULL;
static struct serial_device *serial_current = NULL;

M
Marek Vasut 已提交
33
#if !defined(CONFIG_LWMON) && !defined(CONFIG_PXA250) && !defined(CONFIG_PXA27X)
34
struct serial_device *__default_serial_console (void)
W
wdenk 已提交
35 36 37 38 39 40
{
#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;
41
#elif defined(CONFIG_4xx) \
42 43 44
   || defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) \
   || defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) \
   || defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520)
45
#if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL)
46 47 48 49 50 51 52 53 54 55 56
#if (CONFIG_CONS_INDEX==1)
	return &eserial1_device;
#elif (CONFIG_CONS_INDEX==2)
	return &eserial2_device;
#elif (CONFIG_CONS_INDEX==3)
	return &eserial3_device;
#elif (CONFIG_CONS_INDEX==4)
	return &eserial4_device;
#else
#error "Bad CONFIG_CONS_INDEX."
#endif
57
#else
58
	return &serial0_device;
59
#endif
60 61 62 63 64 65 66 67
#elif defined(CONFIG_MPC512X)
#if (CONFIG_PSC_CONSOLE == 3)
		return &serial3_device;
#elif (CONFIG_PSC_CONSOLE == 6)
		return &serial6_device;
#else
#error "Bad CONFIG_PSC_CONSOLE."
#endif
68 69 70 71 72 73 74 75 76 77
#elif defined(CONFIG_S3C2410)
#if defined(CONFIG_SERIAL1)
	return &s3c24xx_serial0_device;
#elif defined(CONFIG_SERIAL2)
	return &s3c24xx_serial1_device;
#elif defined(CONFIG_SERIAL3)
	return &s3c24xx_serial2_device;
#else
#error "CONFIG_SERIAL? missing."
#endif
78
#elif defined(CONFIG_S5P)
M
Minkyu Kang 已提交
79
#if defined(CONFIG_SERIAL0)
80
	return &s5p_serial0_device;
M
Minkyu Kang 已提交
81
#elif defined(CONFIG_SERIAL1)
82
	return &s5p_serial1_device;
M
Minkyu Kang 已提交
83
#elif defined(CONFIG_SERIAL2)
84
	return &s5p_serial2_device;
M
Minkyu Kang 已提交
85
#elif defined(CONFIG_SERIAL3)
86
	return &s5p_serial3_device;
M
Minkyu Kang 已提交
87 88 89
#else
#error "CONFIG_SERIAL? missing."
#endif
T
Tom Rix 已提交
90 91
#elif defined(CONFIG_OMAP3_ZOOM2)
		return ZOOM2_DEFAULT_SERIAL_DEVICE;
W
wdenk 已提交
92 93 94 95
#else
#error No default console
#endif
}
96 97

struct serial_device *default_serial_console(void) __attribute__((weak, alias("__default_serial_console")));
W
wdenk 已提交
98 99
#endif

100
int serial_register (struct serial_device *dev)
W
wdenk 已提交
101
{
102
#ifndef CONFIG_RELOC_FIXUP_WORKS
W
wdenk 已提交
103 104 105 106 107 108
	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;
109
#endif
W
wdenk 已提交
110 111 112 113 114 115 116

	dev->next = serial_devices;
	serial_devices = dev;

	return 0;
}

W
wdenk 已提交
117
void serial_initialize (void)
W
wdenk 已提交
118 119
{
#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2)
W
wdenk 已提交
120
	serial_register (&serial_smc_device);
W
wdenk 已提交
121 122 123
#endif
#if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
 || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
W
wdenk 已提交
124
	serial_register (&serial_scc_device);
W
wdenk 已提交
125 126
#endif

127 128
#if defined(CONFIG_SYS_NS16550_SERIAL)
#if defined(CONFIG_SYS_NS16550_COM1)
129 130
	serial_register(&eserial1_device);
#endif
131
#if defined(CONFIG_SYS_NS16550_COM2)
132 133
	serial_register(&eserial2_device);
#endif
134
#if defined(CONFIG_SYS_NS16550_COM3)
135 136
	serial_register(&eserial3_device);
#endif
137
#if defined(CONFIG_SYS_NS16550_COM4)
138 139
	serial_register(&eserial4_device);
#endif
140
#endif /* CONFIG_SYS_NS16550_SERIAL */
141 142 143 144 145 146 147 148
#if defined (CONFIG_FFUART)
	serial_register(&serial_ffuart_device);
#endif
#if defined (CONFIG_BTUART)
	serial_register(&serial_btuart_device);
#endif
#if defined (CONFIG_STUART)
	serial_register(&serial_stuart_device);
149 150 151 152 153
#endif
#if defined(CONFIG_S3C2410)
	serial_register(&s3c24xx_serial0_device);
	serial_register(&s3c24xx_serial1_device);
	serial_register(&s3c24xx_serial2_device);
M
Minkyu Kang 已提交
154
#endif
155
#if defined(CONFIG_S5P)
156 157 158 159
	serial_register(&s5p_serial0_device);
	serial_register(&s5p_serial1_device);
	serial_register(&s5p_serial2_device);
	serial_register(&s5p_serial3_device);
160 161 162 163 164 165 166 167 168 169 170 171 172 173
#endif
#if defined(CONFIG_MPC512X)
#if defined(CONFIG_SYS_PSC1)
	serial_register(&serial1_device);
#endif
#if defined(CONFIG_SYS_PSC3)
	serial_register(&serial3_device);
#endif
#if defined(CONFIG_SYS_PSC4)
	serial_register(&serial4_device);
#endif
#if defined(CONFIG_SYS_PSC6)
	serial_register(&serial6_device);
#endif
174
#endif
W
wdenk 已提交
175
	serial_assign (default_serial_console ()->name);
W
wdenk 已提交
176 177
}

178
void serial_stdio_init (void)
W
wdenk 已提交
179
{
180
	struct stdio_dev dev;
W
wdenk 已提交
181 182
	struct serial_device *s = serial_devices;

W
wdenk 已提交
183
	while (s) {
W
wdenk 已提交
184 185 186 187 188 189
		memset (&dev, 0, sizeof (dev));

		strcpy (dev.name, s->name);
		dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;

		dev.start = s->init;
190
		dev.stop = s->uninit;
W
wdenk 已提交
191 192 193 194 195
		dev.putc = s->putc;
		dev.puts = s->puts;
		dev.getc = s->getc;
		dev.tstc = s->tstc;

196
		stdio_register (&dev);
W
wdenk 已提交
197 198 199 200 201

		s = s->next;
	}
}

W
wdenk 已提交
202
int serial_assign (char *name)
W
wdenk 已提交
203 204 205
{
	struct serial_device *s;

W
wdenk 已提交
206 207
	for (s = serial_devices; s; s = s->next) {
		if (strcmp (s->name, name) == 0) {
W
wdenk 已提交
208 209 210 211 212 213 214 215
			serial_current = s;
			return 0;
		}
	}

	return 1;
}

W
wdenk 已提交
216
void serial_reinit_all (void)
W
wdenk 已提交
217 218 219
{
	struct serial_device *s;

W
wdenk 已提交
220 221
	for (s = serial_devices; s; s = s->next) {
		s->init ();
W
wdenk 已提交
222 223 224
	}
}

W
wdenk 已提交
225
int serial_init (void)
W
wdenk 已提交
226
{
W
wdenk 已提交
227 228 229 230
	if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
		struct serial_device *dev = default_serial_console ();

		return dev->init ();
W
wdenk 已提交
231 232
	}

W
wdenk 已提交
233
	return serial_current->init ();
W
wdenk 已提交
234 235
}

W
wdenk 已提交
236
void serial_setbrg (void)
W
wdenk 已提交
237
{
W
wdenk 已提交
238 239 240 241
	if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
		struct serial_device *dev = default_serial_console ();

		dev->setbrg ();
W
wdenk 已提交
242 243 244
		return;
	}

W
wdenk 已提交
245
	serial_current->setbrg ();
W
wdenk 已提交
246 247
}

W
wdenk 已提交
248
int serial_getc (void)
W
wdenk 已提交
249
{
W
wdenk 已提交
250 251 252 253
	if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
		struct serial_device *dev = default_serial_console ();

		return dev->getc ();
W
wdenk 已提交
254 255
	}

W
wdenk 已提交
256
	return serial_current->getc ();
W
wdenk 已提交
257 258
}

W
wdenk 已提交
259
int serial_tstc (void)
W
wdenk 已提交
260
{
W
wdenk 已提交
261 262 263 264
	if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
		struct serial_device *dev = default_serial_console ();

		return dev->tstc ();
W
wdenk 已提交
265 266
	}

W
wdenk 已提交
267
	return serial_current->tstc ();
W
wdenk 已提交
268 269
}

W
wdenk 已提交
270
void serial_putc (const char c)
W
wdenk 已提交
271
{
W
wdenk 已提交
272 273 274 275
	if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
		struct serial_device *dev = default_serial_console ();

		dev->putc (c);
W
wdenk 已提交
276 277 278
		return;
	}

W
wdenk 已提交
279
	serial_current->putc (c);
W
wdenk 已提交
280 281
}

W
wdenk 已提交
282
void serial_puts (const char *s)
W
wdenk 已提交
283
{
W
wdenk 已提交
284 285 286 287
	if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
		struct serial_device *dev = default_serial_console ();

		dev->puts (s);
W
wdenk 已提交
288 289 290
		return;
	}

W
wdenk 已提交
291
	serial_current->puts (s);
W
wdenk 已提交
292
}