uboot/common/stdio.c
<<
>>
Prefs
   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 * SPDX-License-Identifier:     GPL-2.0+
  10 */
  11
  12#include <config.h>
  13#include <common.h>
  14#include <errno.h>
  15#include <stdarg.h>
  16#include <malloc.h>
  17#include <stdio_dev.h>
  18#include <serial.h>
  19#ifdef CONFIG_LOGBUFFER
  20#include <logbuff.h>
  21#endif
  22
  23#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
  24#include <i2c.h>
  25#endif
  26
  27DECLARE_GLOBAL_DATA_PTR;
  28
  29static struct stdio_dev devs;
  30struct stdio_dev *stdio_devices[] = { NULL, NULL, NULL };
  31char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
  32
  33#if defined(CONFIG_SPLASH_SCREEN) && !defined(CONFIG_SYS_DEVICE_NULLDEV)
  34#define CONFIG_SYS_DEVICE_NULLDEV       1
  35#endif
  36
  37#ifdef  CONFIG_SYS_STDIO_DEREGISTER
  38#define CONFIG_SYS_DEVICE_NULLDEV       1
  39#endif
  40
  41#ifdef CONFIG_SYS_DEVICE_NULLDEV
  42static void nulldev_putc(struct stdio_dev *dev, const char c)
  43{
  44        /* nulldev is empty! */
  45}
  46
  47static void nulldev_puts(struct stdio_dev *dev, const char *s)
  48{
  49        /* nulldev is empty! */
  50}
  51
  52static int nulldev_input(struct stdio_dev *dev)
  53{
  54        /* nulldev is empty! */
  55        return 0;
  56}
  57#endif
  58
  59static void stdio_serial_putc(struct stdio_dev *dev, const char c)
  60{
  61        serial_putc(c);
  62}
  63
  64static void stdio_serial_puts(struct stdio_dev *dev, const char *s)
  65{
  66        serial_puts(s);
  67}
  68
  69static int stdio_serial_getc(struct stdio_dev *dev)
  70{
  71        return serial_getc();
  72}
  73
  74static int stdio_serial_tstc(struct stdio_dev *dev)
  75{
  76        return serial_tstc();
  77}
  78
  79/**************************************************************************
  80 * SYSTEM DRIVERS
  81 **************************************************************************
  82 */
  83
  84static void drv_system_init (void)
  85{
  86        struct stdio_dev dev;
  87
  88        memset (&dev, 0, sizeof (dev));
  89
  90        strcpy (dev.name, "serial");
  91        dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
  92        dev.putc = stdio_serial_putc;
  93        dev.puts = stdio_serial_puts;
  94        dev.getc = stdio_serial_getc;
  95        dev.tstc = stdio_serial_tstc;
  96        stdio_register (&dev);
  97
  98#ifdef CONFIG_SYS_DEVICE_NULLDEV
  99        memset (&dev, 0, sizeof (dev));
 100
 101        strcpy (dev.name, "nulldev");
 102        dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
 103        dev.putc = nulldev_putc;
 104        dev.puts = nulldev_puts;
 105        dev.getc = nulldev_input;
 106        dev.tstc = nulldev_input;
 107
 108        stdio_register (&dev);
 109#endif
 110}
 111
 112/**************************************************************************
 113 * DEVICES
 114 **************************************************************************
 115 */
 116struct list_head* stdio_get_list(void)
 117{
 118        return &(devs.list);
 119}
 120
 121struct stdio_dev* stdio_get_by_name(const char *name)
 122{
 123        struct list_head *pos;
 124        struct stdio_dev *dev;
 125
 126        if(!name)
 127                return NULL;
 128
 129        list_for_each(pos, &(devs.list)) {
 130                dev = list_entry(pos, struct stdio_dev, list);
 131                if(strcmp(dev->name, name) == 0)
 132                        return dev;
 133        }
 134
 135        return NULL;
 136}
 137
 138struct stdio_dev* stdio_clone(struct stdio_dev *dev)
 139{
 140        struct stdio_dev *_dev;
 141
 142        if(!dev)
 143                return NULL;
 144
 145        _dev = calloc(1, sizeof(struct stdio_dev));
 146
 147        if(!_dev)
 148                return NULL;
 149
 150        memcpy(_dev, dev, sizeof(struct stdio_dev));
 151
 152        return _dev;
 153}
 154
 155int stdio_register_dev(struct stdio_dev *dev, struct stdio_dev **devp)
 156{
 157        struct stdio_dev *_dev;
 158
 159        _dev = stdio_clone(dev);
 160        if(!_dev)
 161                return -ENODEV;
 162        list_add_tail(&(_dev->list), &(devs.list));
 163        if (devp)
 164                *devp = _dev;
 165
 166        return 0;
 167}
 168
 169int stdio_register(struct stdio_dev *dev)
 170{
 171        return stdio_register_dev(dev, NULL);
 172}
 173
 174/* deregister the device "devname".
 175 * returns 0 if success, -1 if device is assigned and 1 if devname not found
 176 */
 177#ifdef  CONFIG_SYS_STDIO_DEREGISTER
 178int stdio_deregister_dev(struct stdio_dev *dev, int force)
 179{
 180        int l;
 181        struct list_head *pos;
 182        char temp_names[3][16];
 183
 184        /* get stdio devices (ListRemoveItem changes the dev list) */
 185        for (l=0 ; l< MAX_FILES; l++) {
 186                if (stdio_devices[l] == dev) {
 187                        if (force) {
 188                                strcpy(temp_names[l], "nulldev");
 189                                continue;
 190                        }
 191                        /* Device is assigned -> report error */
 192                        return -1;
 193                }
 194                memcpy (&temp_names[l][0],
 195                        stdio_devices[l]->name,
 196                        sizeof(temp_names[l]));
 197        }
 198
 199        list_del(&(dev->list));
 200        free(dev);
 201
 202        /* reassign Device list */
 203        list_for_each(pos, &(devs.list)) {
 204                dev = list_entry(pos, struct stdio_dev, list);
 205                for (l=0 ; l< MAX_FILES; l++) {
 206                        if(strcmp(dev->name, temp_names[l]) == 0)
 207                                stdio_devices[l] = dev;
 208                }
 209        }
 210        return 0;
 211}
 212
 213int stdio_deregister(const char *devname, int force)
 214{
 215        struct stdio_dev *dev;
 216
 217        dev = stdio_get_by_name(devname);
 218
 219        if (!dev) /* device not found */
 220                return -ENODEV;
 221
 222        return stdio_deregister_dev(dev, force);
 223}
 224#endif  /* CONFIG_SYS_STDIO_DEREGISTER */
 225
 226int stdio_init_tables(void)
 227{
 228#if defined(CONFIG_NEEDS_MANUAL_RELOC)
 229        /* already relocated for current ARM implementation */
 230        ulong relocation_offset = gd->reloc_off;
 231        int i;
 232
 233        /* relocate device name pointers */
 234        for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) {
 235                stdio_names[i] = (char *) (((ulong) stdio_names[i]) +
 236                                                relocation_offset);
 237        }
 238#endif /* CONFIG_NEEDS_MANUAL_RELOC */
 239
 240        /* Initialize the list */
 241        INIT_LIST_HEAD(&(devs.list));
 242
 243        return 0;
 244}
 245
 246int stdio_add_devices(void)
 247{
 248#ifdef CONFIG_SYS_I2C
 249        i2c_init_all();
 250#else
 251#if defined(CONFIG_HARD_I2C)
 252        i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 253#endif
 254#endif
 255#ifdef CONFIG_LCD
 256        drv_lcd_init ();
 257#endif
 258#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
 259        drv_video_init ();
 260#endif
 261#ifdef CONFIG_KEYBOARD
 262        drv_keyboard_init ();
 263#endif
 264#ifdef CONFIG_LOGBUFFER
 265        drv_logbuff_init ();
 266#endif
 267        drv_system_init ();
 268        serial_stdio_init ();
 269#ifdef CONFIG_USB_TTY
 270        drv_usbtty_init ();
 271#endif
 272#ifdef CONFIG_NETCONSOLE
 273        drv_nc_init ();
 274#endif
 275#ifdef CONFIG_JTAG_CONSOLE
 276        drv_jtag_console_init ();
 277#endif
 278#ifdef CONFIG_CBMEM_CONSOLE
 279        cbmemc_init();
 280#endif
 281
 282        return 0;
 283}
 284
 285int stdio_init(void)
 286{
 287        stdio_init_tables();
 288        stdio_add_devices();
 289
 290        return 0;
 291}
 292