]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
Merge tag 'video-for-2019.07-rc1' of git://git.denx.de/u-boot-video
authorTom Rini <trini@konsulko.com>
Mon, 15 Apr 2019 11:30:07 +0000 (07:30 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 15 Apr 2019 11:30:07 +0000 (07:30 -0400)
- 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

common/usb_kbd.c
drivers/video/Kconfig
drivers/video/console_normal.c
drivers/video/console_rotate.c
drivers/video/pwm_backlight.c
drivers/video/vidconsole-uclass.c
drivers/video/video-uclass.c
include/configs/sunxi-common.h
include/video.h

index 020f0d4117f7d07f1b22debe8e78b1c78f3f2f64..cc99c6be072044bde788380cfbf231d92a20a277 100644 (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;
index 2eac4b63813d20376ed23256ec01691b5cd74477..43412873c9858731c103cef2d2cd6bff0eb92493 100644 (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
index 2cfa510d5f7d7a0c2830986a21df1dc84d9eeab8..7f01ee94242049e48563c238ba438e580e8e5a93 100644 (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
index f076570335b0f89d85ac755d04c93c47943916f5..71a5c5efba3c0011a772ac6bcf8a769a306d1267 100644 (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;
index bd733f5f1ca5a221ed3844d53e816ceaac08c547..a587977c225045599aafe6b5c0b782ae3495041d 100644 (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);
index 2ca19d40491cedffec50f76e908a1f4905214eba..c31303b56edc3fe2f824f20c14f9fea4ae7c2b5d 100644 (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;
        }
 
index f307cf243bdcb876b355b2e9c30990fbaf1bd318..14aac88d6d277576758ee3369bb4e76a179b8635 100644 (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);
 }
index b01d1c3c843516733a9895866032d1e3958cd14b..ee18260be695894e0c0b1afcc128ffec2af35f19 100644 (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"
index 1d57b48b173807dfb9914793e7ff283ab5962425..485071d0723356abe07ab48d31f0738333eea4f6 100644 (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 */