uboot/drivers/video/sandbox_osd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2018
   4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
   5 */
   6#include <common.h>
   7#include <display.h>
   8#include <dm.h>
   9#include <video_osd.h>
  10
  11#include "sandbox_osd.h"
  12
  13struct sandbox_osd_priv {
  14        uint width;
  15        uint height;
  16        u16 *buf;
  17};
  18
  19static const struct udevice_id sandbox_osd_ids[] = {
  20        { .compatible = "sandbox,sandbox_osd" },
  21        { }
  22};
  23
  24inline u16 make_memval(u8 chr, u8 color)
  25{
  26        return chr * 0x100 + color;
  27}
  28
  29int sandbox_osd_get_info(struct udevice *dev, struct video_osd_info *info)
  30{
  31        struct sandbox_osd_priv *priv = dev_get_priv(dev);
  32
  33        info->width = priv->width;
  34        info->height = priv->height;
  35        info->major_version = 1;
  36        info->minor_version = 0;
  37
  38        return 0;
  39}
  40
  41int sandbox_osd_set_mem(struct udevice *dev, uint col, uint row, u8 *buf,
  42                        size_t buflen, uint count)
  43{
  44        struct sandbox_osd_priv *priv = dev_get_priv(dev);
  45        int pos;
  46        u8 *mem = (u8 *)priv->buf;
  47        int i;
  48
  49        pos = 2 * (row * priv->width + col);
  50
  51        if (pos >= 2 * (priv->width * priv->height))
  52                return -EINVAL;
  53
  54        for (i = 0; i < count; i++)
  55                memcpy(mem + pos + (i * buflen), buf, buflen);
  56
  57        return 0;
  58}
  59
  60int _sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
  61{
  62        struct sandbox_osd_priv *priv = dev_get_priv(dev);
  63        int i;
  64        uint size;
  65
  66        priv->width = col;
  67        priv->height = row;
  68        size = priv->width * priv->height;
  69        if (!priv->buf)
  70                priv->buf = calloc(size, sizeof(u16));
  71        else
  72                priv->buf = realloc(priv->buf, size * sizeof(u16));
  73
  74        if (!priv->buf)
  75                return -ENOMEM;
  76
  77        /* Fill OSD with black spaces */
  78        for (i = 0; i < size; i++)
  79                priv->buf[i] = make_memval(' ', 'k');
  80
  81        return 0;
  82}
  83
  84int sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
  85{
  86        return _sandbox_osd_set_size(dev, col, row);
  87}
  88
  89int sandbox_osd_print(struct udevice *dev, uint col, uint row, ulong color,
  90                      char *text)
  91{
  92        struct sandbox_osd_priv *priv = dev_get_priv(dev);
  93        char cval;
  94        char *p;
  95        int pos;
  96
  97        if (col >= priv->width || row >= priv->height)
  98                return -EINVAL;
  99
 100        switch (color) {
 101        case COLOR_BLACK:
 102                cval = 'k';
 103                break;
 104        case COLOR_WHITE:
 105                cval = 'w';
 106                break;
 107        case COLOR_RED:
 108                cval = 'r';
 109                break;
 110        case COLOR_GREEN:
 111                cval = 'g';
 112                break;
 113        case COLOR_BLUE:
 114                cval = 'b';
 115                break;
 116        default:
 117                return -EINVAL;
 118        }
 119
 120        p = text;
 121        pos = row * priv->width + col;
 122
 123        while (*p)
 124                priv->buf[pos++] = make_memval(*(p++), cval);
 125
 126        return 0;
 127}
 128
 129int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen)
 130{
 131        struct sandbox_osd_priv *priv = dev_get_priv(dev);
 132        uint memsize = 2 * (priv->width * priv->height);
 133
 134        if (buflen < memsize)
 135                return -EINVAL;
 136
 137        memcpy(buf, priv->buf, memsize);
 138
 139        return 0;
 140}
 141
 142static const struct video_osd_ops sandbox_osd_ops = {
 143        .get_info = sandbox_osd_get_info,
 144        .set_mem = sandbox_osd_set_mem,
 145        .set_size = sandbox_osd_set_size,
 146        .print = sandbox_osd_print,
 147};
 148
 149int sandbox_osd_probe(struct udevice *dev)
 150{
 151        return _sandbox_osd_set_size(dev, 10, 10);
 152}
 153
 154U_BOOT_DRIVER(sandbox_osd_drv) = {
 155        .name           = "sandbox_osd_drv",
 156        .id             = UCLASS_VIDEO_OSD,
 157        .ops            = &sandbox_osd_ops,
 158        .of_match       = sandbox_osd_ids,
 159        .probe          = sandbox_osd_probe,
 160        .priv_auto_alloc_size = sizeof(struct sandbox_osd_priv),
 161};
 162