Merge branch 'master' of git://git.denx.de/u-boot-arm
[platform/kernel/u-boot.git] / common / serial.c
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 <stdio_dev.h>
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 static struct serial_device *serial_devices = NULL;
31 static struct serial_device *serial_current = NULL;
32
33 #if !defined(CONFIG_LWMON) && !defined(CONFIG_PXA27X)
34 struct 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) || defined(CONFIG_MPC83xx) \
44    || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) \
45    || defined(CONFIG_SYS_SC520)
46 #if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL)
47 #if (CONFIG_CONS_INDEX==1)
48         return &eserial1_device;
49 #elif (CONFIG_CONS_INDEX==2)
50         return &eserial2_device;
51 #elif (CONFIG_CONS_INDEX==3)
52         return &eserial3_device;
53 #elif (CONFIG_CONS_INDEX==4)
54         return &eserial4_device;
55 #else
56 #error "Bad CONFIG_CONS_INDEX."
57 #endif
58 #elif defined(CONFIG_UART1_CONSOLE)
59                 return &serial1_device;
60 #else
61                 return &serial0_device;
62 #endif
63 #elif defined(CONFIG_MPC512X)
64 #if (CONFIG_PSC_CONSOLE == 3)
65                 return &serial3_device;
66 #elif (CONFIG_PSC_CONSOLE == 6)
67                 return &serial6_device;
68 #else
69 #error "Bad CONFIG_PSC_CONSOLE."
70 #endif
71 #elif defined(CONFIG_S3C2410)
72 #if defined(CONFIG_SERIAL1)
73         return &s3c24xx_serial0_device;
74 #elif defined(CONFIG_SERIAL2)
75         return &s3c24xx_serial1_device;
76 #elif defined(CONFIG_SERIAL3)
77         return &s3c24xx_serial2_device;
78 #else
79 #error "CONFIG_SERIAL? missing."
80 #endif
81 #elif defined(CONFIG_S5PC1XX)
82 #if defined(CONFIG_SERIAL0)
83         return &s5p_serial0_device;
84 #elif defined(CONFIG_SERIAL1)
85         return &s5p_serial1_device;
86 #elif defined(CONFIG_SERIAL2)
87         return &s5p_serial2_device;
88 #elif defined(CONFIG_SERIAL3)
89         return &s5p_serial3_device;
90 #else
91 #error "CONFIG_SERIAL? missing."
92 #endif
93 #elif defined(CONFIG_OMAP3_ZOOM2)
94                 return ZOOM2_DEFAULT_SERIAL_DEVICE;
95 #else
96 #error No default console
97 #endif
98 }
99
100 struct serial_device *default_serial_console(void) __attribute__((weak, alias("__default_serial_console")));
101 #endif
102
103 int serial_register (struct serial_device *dev)
104 {
105 #ifndef CONFIG_RELOC_FIXUP_WORKS
106         dev->init += gd->reloc_off;
107         dev->setbrg += gd->reloc_off;
108         dev->getc += gd->reloc_off;
109         dev->tstc += gd->reloc_off;
110         dev->putc += gd->reloc_off;
111         dev->puts += gd->reloc_off;
112 #endif
113
114         dev->next = serial_devices;
115         serial_devices = dev;
116
117         return 0;
118 }
119
120 void serial_initialize (void)
121 {
122 #if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2)
123         serial_register (&serial_smc_device);
124 #endif
125 #if defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
126  || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
127         serial_register (&serial_scc_device);
128 #endif
129
130 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
131  || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \
132  || defined(CONFIG_MPC5xxx)
133         serial_register(&serial0_device);
134         serial_register(&serial1_device);
135 #endif
136
137 #if defined(CONFIG_SYS_NS16550_SERIAL)
138 #if defined(CONFIG_SYS_NS16550_COM1)
139         serial_register(&eserial1_device);
140 #endif
141 #if defined(CONFIG_SYS_NS16550_COM2)
142         serial_register(&eserial2_device);
143 #endif
144 #if defined(CONFIG_SYS_NS16550_COM3)
145         serial_register(&eserial3_device);
146 #endif
147 #if defined(CONFIG_SYS_NS16550_COM4)
148         serial_register(&eserial4_device);
149 #endif
150 #endif /* CONFIG_SYS_NS16550_SERIAL */
151 #if defined (CONFIG_FFUART)
152         serial_register(&serial_ffuart_device);
153 #endif
154 #if defined (CONFIG_BTUART)
155         serial_register(&serial_btuart_device);
156 #endif
157 #if defined (CONFIG_STUART)
158         serial_register(&serial_stuart_device);
159 #endif
160 #if defined(CONFIG_S3C2410)
161         serial_register(&s3c24xx_serial0_device);
162         serial_register(&s3c24xx_serial1_device);
163         serial_register(&s3c24xx_serial2_device);
164 #endif
165 #if defined(CONFIG_S5PC1XX)
166         serial_register(&s5p_serial0_device);
167         serial_register(&s5p_serial1_device);
168         serial_register(&s5p_serial2_device);
169         serial_register(&s5p_serial3_device);
170 #endif
171 #if defined(CONFIG_MPC512X)
172 #if defined(CONFIG_SYS_PSC1)
173         serial_register(&serial1_device);
174 #endif
175 #if defined(CONFIG_SYS_PSC3)
176         serial_register(&serial3_device);
177 #endif
178 #if defined(CONFIG_SYS_PSC4)
179         serial_register(&serial4_device);
180 #endif
181 #if defined(CONFIG_SYS_PSC6)
182         serial_register(&serial6_device);
183 #endif
184 #endif
185         serial_assign (default_serial_console ()->name);
186 }
187
188 void serial_stdio_init (void)
189 {
190         struct stdio_dev dev;
191         struct serial_device *s = serial_devices;
192
193         while (s) {
194                 memset (&dev, 0, sizeof (dev));
195
196                 strcpy (dev.name, s->name);
197                 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
198
199                 dev.start = s->init;
200                 dev.stop = s->uninit;
201                 dev.putc = s->putc;
202                 dev.puts = s->puts;
203                 dev.getc = s->getc;
204                 dev.tstc = s->tstc;
205
206                 stdio_register (&dev);
207
208                 s = s->next;
209         }
210 }
211
212 int serial_assign (char *name)
213 {
214         struct serial_device *s;
215
216         for (s = serial_devices; s; s = s->next) {
217                 if (strcmp (s->name, name) == 0) {
218                         serial_current = s;
219                         return 0;
220                 }
221         }
222
223         return 1;
224 }
225
226 void serial_reinit_all (void)
227 {
228         struct serial_device *s;
229
230         for (s = serial_devices; s; s = s->next) {
231                 s->init ();
232         }
233 }
234
235 int serial_init (void)
236 {
237         if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
238                 struct serial_device *dev = default_serial_console ();
239
240                 return dev->init ();
241         }
242
243         return serial_current->init ();
244 }
245
246 void serial_setbrg (void)
247 {
248         if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
249                 struct serial_device *dev = default_serial_console ();
250
251                 dev->setbrg ();
252                 return;
253         }
254
255         serial_current->setbrg ();
256 }
257
258 int serial_getc (void)
259 {
260         if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
261                 struct serial_device *dev = default_serial_console ();
262
263                 return dev->getc ();
264         }
265
266         return serial_current->getc ();
267 }
268
269 int serial_tstc (void)
270 {
271         if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
272                 struct serial_device *dev = default_serial_console ();
273
274                 return dev->tstc ();
275         }
276
277         return serial_current->tstc ();
278 }
279
280 void serial_putc (const char c)
281 {
282         if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
283                 struct serial_device *dev = default_serial_console ();
284
285                 dev->putc (c);
286                 return;
287         }
288
289         serial_current->putc (c);
290 }
291
292 void serial_puts (const char *s)
293 {
294         if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
295                 struct serial_device *dev = default_serial_console ();
296
297                 dev->puts (s);
298                 return;
299         }
300
301         serial_current->puts (s);
302 }