From 5cb4860f3df83da9610baf0ac3a4f2836fdfa328 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 19 Sep 2018 20:18:38 +0200 Subject: dm: video: adjust struct vidconsole_priv description The third component of struct vidconsole_priv is ycur. Signed-off-by: Heinrich Schuchardt --- include/video_console.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/video_console.h b/include/video_console.h index 63af741778d..44e7bdbe290 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -45,7 +45,7 @@ enum color_idx { * * @sdev: stdio device, acting as an output sink * @xcur_frac: Current X position, in fractional units (VID_TO_POS(x)) - * @curr_row: Current Y position in pixels (0=top) + * @ycur: Current Y position in pixels (0=top) * @rows: Number of text rows * @cols: Number of text columns * @x_charsize: Character width in pixels -- cgit v1.3.1 From 662f381aad11246109b660a36b9028fd76714be0 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 19 Sep 2018 21:31:48 +0200 Subject: dm: video: support more escape sequences The EFI subsystems needs to know the size of the terminal. If the environment variable stdout = serial,vidconsole this size cannot be read from the video console. So the EFI subsystem sends escape sequences to read the size. With this patch we get support for the following escape sequences: ESC "7" Save cursor position ESC "8" Restore cursor position Signed-off-by: Heinrich Schuchardt --- drivers/video/vidconsole-uclass.c | 75 ++++++++++++++++++++++++++++++++------- include/video_console.h | 28 ++++++++------- 2 files changed, 78 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 0c36a5de0ad..7f95e9c6e56 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -165,6 +165,43 @@ static char *parsenum(char *s, int *num) return end; } +/** + * set_cursor_position() - set cursor position + * + * @priv: private data of the video console + * @row: new row + * @col: new column + */ +static void set_cursor_position(struct vidconsole_priv *priv, int row, int col) +{ + /* + * Ensure we stay in the bounds of the screen. + */ + if (row >= priv->rows) + row = priv->rows - 1; + if (col >= priv->cols) + col = priv->cols - 1; + + priv->ycur = row * priv->y_charsize; + priv->xcur_frac = priv->xstart_frac + + VID_TO_POS(col * priv->x_charsize); +} + +/** + * get_cursor_position() - get cursor position + * + * @priv: private data of the video console + * @row: row + * @col: column + */ +static void get_cursor_position(struct vidconsole_priv *priv, + int *row, int *col) +{ + *row = priv->ycur / priv->y_charsize; + *col = VID_TO_PIXEL(priv->xcur_frac - priv->xstart_frac) / + priv->x_charsize; +} + /* * Process a character while accumulating an escape string. Chars are * accumulated into escape_buf until the end of escape sequence is @@ -180,8 +217,30 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) /* Sanity checking for bogus ESC sequences: */ if (priv->escape_len >= sizeof(priv->escape_buf)) goto error; - if (priv->escape_len == 0 && ch != '[') - goto error; + if (priv->escape_len == 0) { + switch (ch) { + case '7': + /* Save cursor position */ + get_cursor_position(priv, &priv->row_saved, + &priv->col_saved); + priv->escape = 0; + + return; + case '8': { + /* Restore cursor position */ + int row = priv->row_saved; + int col = priv->col_saved; + + set_cursor_position(priv, row, col); + priv->escape = 0; + return; + } + case '[': + break; + default: + goto error; + } + } priv->escape_buf[priv->escape_len++] = ch; @@ -213,17 +272,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) s++; /* ; */ s = parsenum(s, &col); - /* - * Ensure we stay in the bounds of the screen. - */ - if (row >= priv->rows) - row = priv->rows - 1; - if (col >= priv->cols) - col = priv->cols - 1; - - priv->ycur = row * priv->y_charsize; - priv->xcur_frac = priv->xstart_frac + - VID_TO_POS(col * priv->x_charsize); + set_cursor_position(priv, row, col); break; } diff --git a/include/video_console.h b/include/video_console.h index 44e7bdbe290..52a41ac2007 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -43,20 +43,22 @@ enum color_idx { * Drivers must set up @rows, @cols, @x_charsize, @y_charsize in their probe() * method. Drivers may set up @xstart_frac if desired. * - * @sdev: stdio device, acting as an output sink - * @xcur_frac: Current X position, in fractional units (VID_TO_POS(x)) - * @ycur: Current Y position in pixels (0=top) - * @rows: Number of text rows - * @cols: Number of text columns - * @x_charsize: Character width in pixels - * @y_charsize: Character height in pixels + * @sdev: stdio device, acting as an output sink + * @xcur_frac: Current X position, in fractional units (VID_TO_POS(x)) + * @ycur: Current Y position in pixels (0=top) + * @rows: Number of text rows + * @cols: Number of text columns + * @x_charsize: Character width in pixels + * @y_charsize: Character height in pixels * @tab_width_frac: Tab width in fractional units - * @xsize_frac: Width of the display in fractional units + * @xsize_frac: Width of the display in fractional units * @xstart_frac: Left margin for the text console in fractional units - * @last_ch: Last character written to the text console on this line - * @escape: TRUE if currently accumulating an ANSI escape sequence - * @escape_len: Length of accumulated escape sequence so far - * @escape_buf: Buffer to accumulate escape sequence + * @last_ch: Last character written to the text console on this line + * @escape: TRUE if currently accumulating an ANSI escape sequence + * @escape_len: Length of accumulated escape sequence so far + * @col_saved: Saved X position, in fractional units (VID_TO_POS(x)) + * @row_saved: Saved Y position in pixels (0=top) + * @escape_buf: Buffer to accumulate escape sequence */ struct vidconsole_priv { struct stdio_dev sdev; @@ -77,6 +79,8 @@ struct vidconsole_priv { */ int escape; int escape_len; + int row_saved; + int col_saved; char escape_buf[32]; }; -- cgit v1.3.1 From 39a336f116e97d936268b1d317f22a007a01528d Mon Sep 17 00:00:00 2001 From: Mario Six Date: Thu, 27 Sep 2018 09:19:29 +0200 Subject: drivers: Add OSD uclass Some devices offer a text-based OSD (on-screen display) that can be programmatically controlled (i.e. text displayed on). Add a uclass to support such devices. Reviewed-by: Simon Glass Signed-off-by: Mario Six --- drivers/video/Kconfig | 8 ++ drivers/video/Makefile | 1 + drivers/video/video_osd-uclass.c | 45 +++++++++ include/dm/uclass-id.h | 1 + include/video_osd.h | 192 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 247 insertions(+) create mode 100644 drivers/video/video_osd-uclass.c create mode 100644 include/video_osd.h (limited to 'include') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index ed0b21f2a72..4e627a315b9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -683,4 +683,12 @@ config VIDEO_DT_SIMPLEFB The video output is initialized by U-Boot, and kept by the kernel. +config OSD + bool "Enable OSD support" + depends on DM + default n + help + This supports drivers that provide a OSD (on-screen display), which + is a (usually text-oriented) graphics buffer to show information on + a display. endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 0f41a23193a..9cec564373e 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o obj-$(CONFIG_LD9040) += ld9040.o obj-$(CONFIG_LG4573) += lg4573.o obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o +obj-$(CONFIG_OSD) += video_osd-uclass.o obj-$(CONFIG_PXA_LCD) += pxa_lcd.o obj-$(CONFIG_S6E8AX0) += s6e8ax0.o obj-$(CONFIG_SCF0403_LCD) += scf0403_lcd.o diff --git a/drivers/video/video_osd-uclass.c b/drivers/video/video_osd-uclass.c new file mode 100644 index 00000000000..82136a292bf --- /dev/null +++ b/drivers/video/video_osd-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#include +#include +#include + +int video_osd_get_info(struct udevice *dev, struct video_osd_info *info) +{ + struct video_osd_ops *ops = video_osd_get_ops(dev); + + return ops->get_info(dev, info); +} + +int video_osd_set_mem(struct udevice *dev, uint col, uint row, u8 *buf, + size_t buflen, uint count) +{ + struct video_osd_ops *ops = video_osd_get_ops(dev); + + return ops->set_mem(dev, col, row, buf, buflen, count); +} + +int video_osd_set_size(struct udevice *dev, uint col, uint row) +{ + struct video_osd_ops *ops = video_osd_get_ops(dev); + + return ops->set_size(dev, col, row); +} + +int video_osd_print(struct udevice *dev, uint col, uint row, ulong color, + char *text) +{ + struct video_osd_ops *ops = video_osd_get_ops(dev); + + return ops->print(dev, col, row, color, text); +} + +UCLASS_DRIVER(video_osd) = { + .id = UCLASS_VIDEO_OSD, + .name = "video_osd", + .flags = DM_UC_FLAG_SEQ_ALIAS, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 7027ea076db..15abdce5e52 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -92,6 +92,7 @@ enum uclass_id { UCLASS_VIDEO, /* Video or LCD device */ UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */ + UCLASS_VIDEO_OSD, /* On-screen display */ UCLASS_WDT, /* Watchdot Timer driver */ UCLASS_COUNT, diff --git a/include/video_osd.h b/include/video_osd.h new file mode 100644 index 00000000000..01ac94b425c --- /dev/null +++ b/include/video_osd.h @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#ifndef _VIDEO_OSD_H_ +#define _VIDEO_OSD_H_ + +struct video_osd_info { + /* The width of the OSD display in columns */ + uint width; + /* The height of the OSD display in rows */ + uint height; + /* The major version of the OSD device */ + uint major_version; + /* The minor version of the OSD device */ + uint minor_version; +}; + +/** + * struct video_osd_ops - driver operations for OSD uclass + * + * The OSD uclass implements support for text-oriented on-screen displays, + * which are taken to be devices that independently display a graphical + * text-based overlay over the video output of an associated display. + * + * The functions defined by the uclass support writing text to the display in + * either a generic form (by specifying a string, a driver-specific color value + * for the text, and screen coordinates in rows and columns) or a + * driver-specific form (by specifying "raw" driver-specific data to display at + * a given coordinate). + * + * Functions to read device information and set the size of the virtual OSD + * screen (in rows and columns) are also supported. + * + * Drivers should support these operations unless otherwise noted. These + * operations are intended to be used by uclass code, not directly from + * other code. + */ +struct video_osd_ops { + /** + * get_info() - Get information about a OSD instance + * + * A OSD instance may keep some internal data about itself. This + * function can be used to access this data. + * + * @dev: OSD instance to query. + * @info: Pointer to a structure that takes the information read + * from the OSD instance. + * @return 0 if OK, -ve on error. + */ + int (*get_info)(struct udevice *dev, struct video_osd_info *info); + + /** + * set_mem() - Write driver-specific text data to OSD screen + * + * The passed data are device-specific, and it's up to the driver how + * to interpret them. How the count parameter is interpreted is also + * driver-specific; most likely the given data will be written to the + * OSD count times back-to-back, which is e.g. convenient for filling + * areas of the OSD with a single character. + * + * For example a invocation of + * + * video_osd_set_mem(dev, 0, 0, "A", 1, 10); + * + * will write the device-specific text data "A" to the positions (0, 0) + * to (9, 0) on the OSD. + * + * Device-specific text data may, e.g. be a special encoding of glyphs + * to display and color values in binary format. + * + * @dev: OSD instance to write to. + * @col: Horizontal character coordinate to write to. + * @row Vertical character coordinate to write to. + * @buf: Array containing device-specific data to write to the + * specified coordinate on the OSD screen. + * @buflen: Length of the data in the passed buffer (in byte). + * @count: Write count many repetitions of the given text data + * @return 0 if OK, -ve on error. + */ + int (*set_mem)(struct udevice *dev, uint col, uint row, u8 *buf, + size_t buflen, uint count); + + /** + * set_size() - Set the position and dimension of the OSD's + * writeable window + * + * @dev: OSD instance to write to. + * @col The number of characters in the window's columns + * @row The number of characters in the window's rows + * @return 0 if OK, -ve on error. + */ + int (*set_size)(struct udevice *dev, uint col, uint row); + + /** + * print() - Print a string in a given color to specified coordinates + * on the OSD + * + * @dev: OSD instance to write to. + * @col The x-coordinate of the position the string should be + * written to + * @row The y-coordinate of the position the string should be + * written to + * @color: The color in which the specified string should be + * printed; the interpretation of the value is + * driver-specific, and possible values should be defined + * e.g. in a driver include file. + * @text: The string data that should be printed on the OSD + * @return 0 if OK, -ve on error. + */ + int (*print)(struct udevice *dev, uint col, uint row, ulong color, + char *text); +}; + +#define video_osd_get_ops(dev) ((struct video_osd_ops *)(dev)->driver->ops) + +/** + * video_osd_get_info() - Get information about a OSD instance + * + * A OSD instance may keep some internal data about itself. This function can + * be used to access this data. + * + * @dev: OSD instance to query. + * @info: Pointer to a structure that takes the information read from the + * OSD instance. + * @return 0 if OK, -ve on error. + */ +int video_osd_get_info(struct udevice *dev, struct video_osd_info *info); + +/** + * video_osd_set_mem() - Write text data to OSD memory + * + * The passed data are device-specific, and it's up to the driver how to + * interpret them. How the count parameter is interpreted is also + * driver-specific; most likely the given data will be written to the OSD count + * times back-to-back, which is e.g. convenient for filling areas of the OSD + * with a single character. + * + * For example a invocation of + * + * video_osd_set_mem(dev, 0, 0, "A", 1, 10); + * + * will write the device-specific text data "A" to the positions (0, 0) to (9, + * 0) on the OSD. + * + * Device-specific text data may, e.g. be a special encoding of glyphs to + * display and color values in binary format. + * + * @dev: OSD instance to write to. + * @col: Horizontal character coordinate to write to. + * @row Vertical character coordinate to write to. + * @buf: Array containing device-specific data to write to the specified + * coordinate on the OSD screen. + * @buflen: Length of the data in the passed buffer (in byte). + * @count: Write count many repetitions of the given text data + * @return 0 if OK, -ve on error. + */ +int video_osd_set_mem(struct udevice *dev, uint col, uint row, u8 *buf, + size_t buflen, uint count); + +/** + * video_osd_set_size() - Set the position and dimension of the OSD's + * writeable window + * + * @dev: OSD instance to write to. + * @col The number of characters in the window's columns + * @row The number of characters in the window's rows + * @return 0 if OK, -ve on error. + */ +int video_osd_set_size(struct udevice *dev, uint col, uint row); + +/** + * video_osd_print() - Print a string in a given color to specified coordinates + * on the OSD + * + * @dev: OSD instance to write to. + * @col The x-coordinate of the position the string should be written + * to + * @row The y-coordinate of the position the string should be written + * to + * @color: The color in which the specified string should be printed; the + * interpretation of the value is driver-specific, and possible + * values should be defined e.g. in a driver include file. + * @text: The string data that should be printed on the OSD + * @return 0 if OK, -ve on error. + */ +int video_osd_print(struct udevice *dev, uint col, uint row, ulong color, + char *text); + +#endif /* !_VIDEO_OSD_H_ */ -- cgit v1.3.1 From 41f67e3bf343e7d8408956574f83ef7c13d2d0b4 Mon Sep 17 00:00:00 2001 From: Mario Six Date: Thu, 27 Sep 2018 09:19:32 +0200 Subject: test: Add ut_asserteq_mem Add a unit test assert-method, which compares two given memory areas for byte-wise equality. Signed-off-by: Mario Six Reviewed-by: Simon Glass --- include/test/ut.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/test/ut.h b/include/test/ut.h index fce75fd12a0..19bcb8c3748 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -78,6 +78,24 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line, } \ } +/* Assert that two memory areas are equal */ +#define ut_asserteq_mem(expr1, expr2, len) { \ + const u8 *val1 = (u8 *)(expr1), *val2 = (u8 *)(expr2); \ + const uint __len = len; \ + \ + if (memcmp(val1, val2, __len)) { \ + char __buf1[64 + 1] = "\0"; \ + char __buf2[64 + 1] = "\0"; \ + bin2hex(__buf1, val1, min(__len, (uint)32)); \ + bin2hex(__buf2, val2, min(__len, (uint)32)); \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + #expr1 " = " #expr2, \ + "Expected \"%s\", got \"%s\"", \ + __buf1, __buf2); \ + return CMD_RET_FAILURE; \ + } \ +} + /* Assert that two pointers are equal */ #define ut_asserteq_ptr(expr1, expr2) { \ const void *val1 = (expr1), *val2 = (expr2); \ -- cgit v1.3.1 From cc0dae08c69a0a2a1772d8358e20020d2829910a Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Mon, 17 Sep 2018 17:45:03 +0100 Subject: include/video.h: Remove declaration of functions that don't exist. video_init, video_putc and video_puts functions are not implemented anywhere, remove their declaration from the header. Signed-off-by: Liviu Dudau Reviewed-by: Simon Glass Reviewed-by: Heiko Schocher --- include/video.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include') diff --git a/include/video.h b/include/video.h index ddc2eeb5a95..e7fc5c94e2e 100644 --- a/include/video.h +++ b/include/video.h @@ -198,12 +198,6 @@ void video_set_default_colors(struct video_priv *priv); /* Video functions */ -struct stdio_dev; - -int video_init(void *videobase); -void video_putc(struct stdio_dev *dev, const char c); -void video_puts(struct stdio_dev *dev, const char *s); - /** * Display a BMP format bitmap on the screen * -- cgit v1.3.1