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