Merge tag 'video-for-2019.07-rc1' of git://git.denx.de/u-boot-video
- optional backlight PWM polarity config via polarity cell
- bug fix for ASCII characters > 127
- ANSI sequence handling extensions (implement clear line,
reverse video and relative cursor movement commands)
- preparation for doing character set translations
- left/right and up/down arrow keys translation to ANSI
control sequences for cursor movement to fix selection
with an USB keyboard in bootmenu
- CONFIG_SYS_WHITE_ON_BLACK font scheme configuration for
sunxi boards
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 @@
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 @@
}
/* 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;
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 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/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 @@
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 @@
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 @@
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 @@
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;
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 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 @@
(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 @@
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);
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 2ca19d4..c31303b 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -259,6 +259,43 @@
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;
@@ -309,6 +346,25 @@
}
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;
@@ -360,6 +416,13 @@
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 +431,11 @@
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 */
@@ -392,6 +457,32 @@
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);
@@ -429,23 +520,9 @@
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;
}
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 @@
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/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 @@
"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"
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 @@
* 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 @@
bool flush_dcache;
ushort *cmap;
u8 fg_col_idx;
+ u8 bg_col_idx;
};
/* Placeholder - there are no video operations at present */