From 57e7775413cfd4ada728c4e60df64895dfa37e4e Mon Sep 17 00:00:00 2001 From: Stefan Mavrodiev Date: Fri, 12 Apr 2019 08:56:27 +0300 Subject: video: backlight: Parse PWM polarity cell This patch enables the reading of the polarity cell from a PWM phandle and calls pwm_set_invert(). Not all platforms have polarity cell, so skip if it's not pressent. Signed-off-by: Stefan Mavrodiev Reviewed-by: Anatolij Gustschin --- drivers/video/pwm_backlight.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c index bd733f5..a587977 100644 --- a/drivers/video/pwm_backlight.c +++ b/drivers/video/pwm_backlight.c @@ -39,6 +39,12 @@ struct pwm_backlight_priv { struct udevice *pwm; uint channel; uint period_ns; + /* + * the polarity of one PWM + * 0: normal polarity + * 1: inverted polarity + */ + bool polarity; u32 *levels; int num_levels; uint default_level; @@ -57,7 +63,10 @@ static int set_pwm(struct pwm_backlight_priv *priv) (priv->max_level - priv->min_level + 1); ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns, duty_cycle); + if (ret) + return log_ret(ret); + ret = pwm_set_invert(priv->pwm, priv->channel, priv->polarity); return log_ret(ret); } @@ -202,6 +211,8 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) return log_msg_ret("Not enough arguments to pwm\n", -EINVAL); priv->channel = args.args[0]; priv->period_ns = args.args[1]; + if (args.args_count > 2) + priv->polarity = args.args[2]; index = dev_read_u32_default(dev, "default-brightness-level", 255); cell = dev_read_prop(dev, "brightness-levels", &len); -- cgit v1.1 From 96c9bf7e2ae2ac331574cf5017a0381d184a45a8 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Mar 2019 01:29:55 +0000 Subject: video/console: Fix DM_VIDEO font glyph array indexing When the character to be printed on a DM_VIDEO console is from the "extended ASCII" range (0x80 - 0xff), it will be treated as a negative number, as it's declared as a signed char. This leads to negative array indicies into the glyph bitmap array, and random garbled characters. Cast the character to an unsigned type to make the index always positive and avoid an out-of-bounds access. Signed-off-by: Andre Przywara Reviewed-by: Simon Glass --- drivers/video/console_normal.c | 3 ++- drivers/video/console_rotate.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 2cfa510..7f01ee9 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -84,7 +84,8 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y, return -EAGAIN; for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { - uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row]; + unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row; + uchar bits = video_fontdata[idx]; switch (vid_priv->bpix) { #ifdef CONFIG_VIDEO_BPP8 diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c index f076570..71a5c5e 100644 --- a/drivers/video/console_rotate.c +++ b/drivers/video/console_rotate.c @@ -90,7 +90,7 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch) int i, col; int mask = 0x80; void *line; - uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) * vid_priv->line_length - (y + 1) * pbytes; @@ -222,7 +222,8 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch) VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix); for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { - uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row]; + unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row; + uchar bits = video_fontdata[idx]; switch (vid_priv->bpix) { #ifdef CONFIG_VIDEO_BPP8 @@ -348,7 +349,7 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch) void *line = vid_priv->fb + (vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) * vid_priv->line_length + y * pbytes; - uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) return -EAGAIN; -- cgit v1.1 From eabb0725d4224efd103779f78e75627d8abc91e6 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Mar 2019 01:29:56 +0000 Subject: video/console: Implement reverse video ANSI sequence for DM_VIDEO The video console for DM_VIDEO compliant drivers only understands a very small number of ANSI sequences. First and foremost it misses the "reverse video" command, which is used by our own bootmenu command to highlight the selected entry. To avoid forcing people to use their imagination when using the bootmenu, let's just implement the rather simple reverse effect. We need to store the background colour index for that, so that we can recalculate both the foreground and background colour pixel values. Signed-off-by: Andre Przywara Reviewed-by: Simon Glass [agust: merged BG color escape seq change to fix "ut dm video_ansi" test] Signed-off-by: Anatolij Gustschin --- drivers/video/vidconsole-uclass.c | 13 +++++++++++-- drivers/video/video-uclass.c | 1 + include/video.h | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 2ca19d4..3ff65f3 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -360,6 +360,13 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) vid_priv->colour_fg = vid_console_color( vid_priv, vid_priv->fg_col_idx); break; + case 7: + /* reverse video */ + vid_priv->colour_fg = vid_console_color( + vid_priv, vid_priv->bg_col_idx); + vid_priv->colour_bg = vid_console_color( + vid_priv, vid_priv->fg_col_idx); + break; case 30 ... 37: /* foreground color */ vid_priv->fg_col_idx &= ~7; @@ -368,9 +375,11 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) vid_priv, vid_priv->fg_col_idx); break; case 40 ... 47: - /* background color */ + /* background color, also mask the bold bit */ + vid_priv->bg_col_idx &= ~0xf; + vid_priv->bg_col_idx |= val - 40; vid_priv->colour_bg = vid_console_color( - vid_priv, val - 40); + vid_priv, vid_priv->bg_col_idx); break; default: /* ignore unsupported SGR parameter */ diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index f307cf2..14aac88 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -136,6 +136,7 @@ void video_set_default_colors(struct udevice *dev, bool invert) back = temp; } priv->fg_col_idx = fore; + priv->bg_col_idx = back; priv->colour_fg = vid_console_color(priv, fore); priv->colour_bg = vid_console_color(priv, back); } diff --git a/include/video.h b/include/video.h index 1d57b48..485071d 100644 --- a/include/video.h +++ b/include/video.h @@ -70,6 +70,7 @@ enum video_log2_bpp { * the LCD is updated * @cmap: Colour map for 8-bit-per-pixel displays * @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color) + * @bg_col_idx: Background color code (bit 3 = bold, bit 0-2 = color) */ struct video_priv { /* Things set up by the driver: */ @@ -92,6 +93,7 @@ struct video_priv { bool flush_dcache; ushort *cmap; u8 fg_col_idx; + u8 bg_col_idx; }; /* Placeholder - there are no video operations at present */ -- cgit v1.1 From 29c158b90d9fe1b8e007ee6b43f85c7f4b5f848b Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Mar 2019 01:29:57 +0000 Subject: video/console: Implement relative cursor movement ANSI handling The ANSI terminal escapce sequence standard defines relative cursor movement commands (ESC [ A-F). So far the DM_VIDEO console code was ignoring them. Interpret those sequences and move the cursor by the requested amount of rows or columns in the right direction. This brings the code on par with the legacy video console driver (cfb_console). Signed-off-by: Andre Przywara Reviewed-by: Simon Glass --- drivers/video/vidconsole-uclass.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 3ff65f3..6cf9124 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -259,6 +259,43 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) priv->escape = 0; switch (ch) { + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': { + int row, col, num; + char *s = priv->escape_buf; + + /* + * Cursor up/down: [%dA, [%dB, [%dE, [%dF + * Cursor left/right: [%dD, [%dC + */ + s++; /* [ */ + s = parsenum(s, &num); + if (num == 0) /* No digit in sequence ... */ + num = 1; /* ... means "move by 1". */ + + get_cursor_position(priv, &row, &col); + if (ch == 'A' || ch == 'F') + row -= num; + if (ch == 'C') + col += num; + if (ch == 'D') + col -= num; + if (ch == 'B' || ch == 'E') + row += num; + if (ch == 'E' || ch == 'F') + col = 0; + if (col < 0) + col = 0; + if (row < 0) + row = 0; + /* Right and bottom overflows are handled in the callee. */ + set_cursor_position(priv, row, col); + break; + } case 'H': case 'f': { int row, col; -- cgit v1.1 From 4422294cbe37e3b2bcbbb066e0d53411880cf07e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Mar 2019 01:29:58 +0000 Subject: video/console: Implement ANSI clear line command There is a standard ANSI terminal escape sequence to clear a whole line of text. So far the DM_VIDEO console was missing this code. Detect the sequence and use vidconsole_set_row with the background colour to fix this omission. Signed-off-by: Andre Przywara Reviewed-by: Simon Glass --- drivers/video/vidconsole-uclass.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 6cf9124..cf2f0df 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -346,6 +346,25 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) } break; } + case 'K': { + struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); + int mode; + + /* + * Clear (parts of) current line + * [0K - clear line to end + * [2K - clear entire line + */ + parsenum(priv->escape_buf + 1, &mode); + + if (mode == 2) { + int row, col; + + get_cursor_position(priv, &row, &col); + vidconsole_set_row(dev, row, vid_priv->colour_bg); + } + break; + } case 'm': { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); char *s = priv->escape_buf; -- cgit v1.1 From 7035ec3cb35c593a492cb929ba8fe9d991d0416d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Mar 2019 01:29:59 +0000 Subject: video/console: Factor out actual character output In preparation for doing character set translations, factor out the actual glyph display functionality into a separate function. This will be used in a subsequent patch. Signed-off-by: Andre Przywara Reviewed-by: Simon Glass --- drivers/video/vidconsole-uclass.c | 42 +++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index cf2f0df..c31303b 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -457,6 +457,32 @@ error: priv->escape = 0; } +/* Put that actual character on the screen (using the CP437 code page). */ +static int vidconsole_output_glyph(struct udevice *dev, char ch) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + int ret; + + /* + * Failure of this function normally indicates an unsupported + * colour depth. Check this and return an error to help with + * diagnosis. + */ + ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch); + if (ret == -EAGAIN) { + vidconsole_newline(dev); + ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch); + } + if (ret < 0) + return ret; + priv->xcur_frac += ret; + priv->last_ch = ch; + if (priv->xcur_frac >= priv->xsize_frac) + vidconsole_newline(dev); + + return 0; +} + int vidconsole_put_char(struct udevice *dev, char ch) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); @@ -494,23 +520,9 @@ int vidconsole_put_char(struct udevice *dev, char ch) priv->last_ch = 0; break; default: - /* - * Failure of this function normally indicates an unsupported - * colour depth. Check this and return an error to help with - * diagnosis. - */ - ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch); - if (ret == -EAGAIN) { - vidconsole_newline(dev); - ret = vidconsole_putc_xy(dev, priv->xcur_frac, - priv->ycur, ch); - } + ret = vidconsole_output_glyph(dev, ch); if (ret < 0) return ret; - priv->xcur_frac += ret; - priv->last_ch = ch; - if (priv->xcur_frac >= priv->xsize_frac) - vidconsole_newline(dev); break; } -- cgit v1.1 From c99ffd72ab1e94d9ffcf61d09f25b75f6a8baaaa Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Mar 2019 01:30:01 +0000 Subject: usb: kbd: Properly translate up/down arrow keys So far arrows key pressed on an USB keyboard got translated to some low ASCII control sequences (Ctrl+N, Ctrl+P). Some programs understand these codes, but the standard for those keys is to use ANSI control sequences for cursor movement (ESC [ A). Our own boot menu is a victim of this, currently we cannot change the selection with an USB keyboard due to this. Since we already implement a queue for USB key codes, we can just insert the three character ANSI sequence into the key buffer. This fixes the bootmenu, and is more universal for other users (UEFI) as well. Signed-off-by: Andre Przywara Reviewed-by: Simon Glass --- common/usb_kbd.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 020f0d4..cc99c6b 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -145,6 +145,12 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, char c) data->usb_kbd_buffer[data->usb_in_pointer] = c; } +static void usb_kbd_put_sequence(struct usb_kbd_pdata *data, char *s) +{ + for (; *s; s++) + usb_kbd_put_queue(data, *s); +} + /* * Set the LEDs. Since this is used in the irq routine, the control job is * issued with a timeout of 0. This means, that the job is queued without @@ -235,9 +241,25 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode, } /* Report keycode if any */ - if (keycode) { + if (keycode) debug("%c", keycode); + + switch (keycode) { + case 0x0e: /* Down arrow key */ + usb_kbd_put_sequence(data, "\e[B"); + break; + case 0x10: /* Up arrow key */ + usb_kbd_put_sequence(data, "\e[A"); + break; + case 0x06: /* Right arrow key */ + usb_kbd_put_sequence(data, "\e[C"); + break; + case 0x02: /* Left arrow key */ + usb_kbd_put_sequence(data, "\e[D"); + break; + default: usb_kbd_put_queue(data, keycode); + break; } return 0; -- cgit v1.1 From 7b64a70a3a0113f9cd5356b3260d4740edb03265 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Mar 2019 01:30:02 +0000 Subject: sunxi: allow boards to de-select SYS_WHITE_ON_BLACK font scheme In the sunxi-common.h config header we unconditionally define CONFIG_SYS_WHITE_ON_BLACK, although it's actually a Kconfig option which could be individually selected by a user. Remove this #define from the header and let it default to "y" on sunxi boards (like we do for other platforms). Signed-off-by: Andre Przywara Reviewed-by: Simon Glass --- drivers/video/Kconfig | 2 +- include/configs/sunxi-common.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2eac4b6..4341287 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -120,7 +120,7 @@ config CONSOLE_TRUETYPE_SIZE config SYS_WHITE_ON_BLACK bool "Display console as white on a black background" - default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || TEGRA || X86 + default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || TEGRA || X86 || ARCH_SUNXI help Normally the display is black on a white background, Enable this option to invert this, i.e. white on a black background. This can be diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index b01d1c3..ee18260 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -449,7 +449,6 @@ extern int soft_i2c_gpio_scl; "stdout=serial,vga\0" \ "stderr=serial,vga\0" #elif CONFIG_DM_VIDEO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONSOLE_STDOUT_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" -- cgit v1.1