]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/stdio.c
i2c, soft-i2c: switch to new multibus/multiadapter support
[karo-tx-uboot.git] / common / stdio.c
1 /*
2  * Copyright (C) 2009 Sergey Kubushyn <ksi@koi8.net>
3  *
4  * Changes for multibus/multiadapter I2C support.
5  *
6  * (C) Copyright 2000
7  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 #include <config.h>
29 #include <common.h>
30 #include <stdarg.h>
31 #include <malloc.h>
32 #include <stdio_dev.h>
33 #include <serial.h>
34 #ifdef CONFIG_LOGBUFFER
35 #include <logbuff.h>
36 #endif
37
38 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
39 #include <i2c.h>
40 #endif
41
42 DECLARE_GLOBAL_DATA_PTR;
43
44 static struct stdio_dev devs;
45 struct stdio_dev *stdio_devices[] = { NULL, NULL, NULL };
46 char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
47
48 #if defined(CONFIG_SPLASH_SCREEN) && !defined(CONFIG_SYS_DEVICE_NULLDEV)
49 #define CONFIG_SYS_DEVICE_NULLDEV       1
50 #endif
51
52
53 #ifdef CONFIG_SYS_DEVICE_NULLDEV
54 void nulldev_putc(const char c)
55 {
56         /* nulldev is empty! */
57 }
58
59 void nulldev_puts(const char *s)
60 {
61         /* nulldev is empty! */
62 }
63
64 int nulldev_input(void)
65 {
66         /* nulldev is empty! */
67         return 0;
68 }
69 #endif
70
71 /**************************************************************************
72  * SYSTEM DRIVERS
73  **************************************************************************
74  */
75
76 static void drv_system_init (void)
77 {
78         struct stdio_dev dev;
79
80         memset (&dev, 0, sizeof (dev));
81
82         strcpy (dev.name, "serial");
83         dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
84         dev.putc = serial_putc;
85         dev.puts = serial_puts;
86         dev.getc = serial_getc;
87         dev.tstc = serial_tstc;
88         stdio_register (&dev);
89
90 #ifdef CONFIG_SYS_DEVICE_NULLDEV
91         memset (&dev, 0, sizeof (dev));
92
93         strcpy (dev.name, "nulldev");
94         dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
95         dev.putc = nulldev_putc;
96         dev.puts = nulldev_puts;
97         dev.getc = nulldev_input;
98         dev.tstc = nulldev_input;
99
100         stdio_register (&dev);
101 #endif
102 }
103
104 /**************************************************************************
105  * DEVICES
106  **************************************************************************
107  */
108 struct list_head* stdio_get_list(void)
109 {
110         return &(devs.list);
111 }
112
113 struct stdio_dev* stdio_get_by_name(const char *name)
114 {
115         struct list_head *pos;
116         struct stdio_dev *dev;
117
118         if(!name)
119                 return NULL;
120
121         list_for_each(pos, &(devs.list)) {
122                 dev = list_entry(pos, struct stdio_dev, list);
123                 if(strcmp(dev->name, name) == 0)
124                         return dev;
125         }
126
127         return NULL;
128 }
129
130 struct stdio_dev* stdio_clone(struct stdio_dev *dev)
131 {
132         struct stdio_dev *_dev;
133
134         if(!dev)
135                 return NULL;
136
137         _dev = calloc(1, sizeof(struct stdio_dev));
138
139         if(!_dev)
140                 return NULL;
141
142         memcpy(_dev, dev, sizeof(struct stdio_dev));
143
144         return _dev;
145 }
146
147 int stdio_register (struct stdio_dev * dev)
148 {
149         struct stdio_dev *_dev;
150
151         _dev = stdio_clone(dev);
152         if(!_dev)
153                 return -1;
154         list_add_tail(&(_dev->list), &(devs.list));
155         return 0;
156 }
157
158 /* deregister the device "devname".
159  * returns 0 if success, -1 if device is assigned and 1 if devname not found
160  */
161 #ifdef  CONFIG_SYS_STDIO_DEREGISTER
162 int stdio_deregister(const char *devname)
163 {
164         int l;
165         struct list_head *pos;
166         struct stdio_dev *dev;
167         char temp_names[3][16];
168
169         dev = stdio_get_by_name(devname);
170
171         if(!dev) /* device not found */
172                 return -1;
173         /* get stdio devices (ListRemoveItem changes the dev list) */
174         for (l=0 ; l< MAX_FILES; l++) {
175                 if (stdio_devices[l] == dev) {
176                         /* Device is assigned -> report error */
177                         return -1;
178                 }
179                 memcpy (&temp_names[l][0],
180                         stdio_devices[l]->name,
181                         sizeof(temp_names[l]));
182         }
183
184         list_del(&(dev->list));
185
186         /* reassign Device list */
187         list_for_each(pos, &(devs.list)) {
188                 dev = list_entry(pos, struct stdio_dev, list);
189                 for (l=0 ; l< MAX_FILES; l++) {
190                         if(strcmp(dev->name, temp_names[l]) == 0)
191                                 stdio_devices[l] = dev;
192                 }
193         }
194         return 0;
195 }
196 #endif  /* CONFIG_SYS_STDIO_DEREGISTER */
197
198 int stdio_init (void)
199 {
200 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
201         /* already relocated for current ARM implementation */
202         ulong relocation_offset = gd->reloc_off;
203         int i;
204
205         /* relocate device name pointers */
206         for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) {
207                 stdio_names[i] = (char *) (((ulong) stdio_names[i]) +
208                                                 relocation_offset);
209         }
210 #endif /* CONFIG_NEEDS_MANUAL_RELOC */
211
212         /* Initialize the list */
213         INIT_LIST_HEAD(&(devs.list));
214
215 #ifdef CONFIG_ARM_DCC
216         drv_arm_dcc_init ();
217 #endif
218 #ifdef CONFIG_SYS_I2C
219         i2c_init_all();
220 #else
221 #if defined(CONFIG_HARD_I2C)
222         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
223 #endif
224 #endif
225 #ifdef CONFIG_LCD
226         drv_lcd_init ();
227 #endif
228 #if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
229         drv_video_init ();
230 #endif
231 #ifdef CONFIG_KEYBOARD
232         drv_keyboard_init ();
233 #endif
234 #ifdef CONFIG_LOGBUFFER
235         drv_logbuff_init ();
236 #endif
237         drv_system_init ();
238         serial_stdio_init ();
239 #ifdef CONFIG_USB_TTY
240         drv_usbtty_init ();
241 #endif
242 #ifdef CONFIG_NETCONSOLE
243         drv_nc_init ();
244 #endif
245 #ifdef CONFIG_JTAG_CONSOLE
246         drv_jtag_console_init ();
247 #endif
248 #ifdef CONFIG_CBMEM_CONSOLE
249         cbmemc_init();
250 #endif
251         return (0);
252 }