- 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
 -----BEGIN PGP SIGNATURE-----
 
 iGwEABECACwWIQSC4hxrSoIUVfFO0kRM6ATMmsalXAUCXLN1fg4cYWd1c3RAZGVu
 eC5kZQAKCRBM6ATMmsalXJKfAJ4mlkJRm5oXcjjZqVkI+Qm1NdKpPACfUuvrDOgo
 MzubX1rLQS+h8BBlG+s=
 =7pd3
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Tom Rini 2019-04-15 07:30:07 -04:00
commit 939803e130
9 changed files with 138 additions and 24 deletions

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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;
@ -309,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;
@ -360,6 +416,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 +431,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 */
@ -392,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);
@ -429,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;
}

View file

@ -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);
}

View file

@ -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"

View file

@ -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 */