]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
72cded9e SG |
2 | /* |
3 | * Copyright (c) 2015 Google, Inc | |
31547259 | 4 | * (C) Copyright 2015 |
72cded9e | 5 | * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com |
31547259 | 6 | * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com> |
72cded9e SG |
7 | */ |
8 | ||
d678a59d | 9 | #include <common.h> |
5ea38f95 | 10 | #include <charset.h> |
72cded9e SG |
11 | #include <dm.h> |
12 | #include <video.h> | |
13 | #include <video_console.h> | |
14 | #include <video_font.h> /* Get font data, width and height */ | |
31547259 | 15 | #include "vidconsole_internal.h" |
72cded9e | 16 | |
31547259 | 17 | static int console_set_row(struct udevice *dev, uint row, int clr) |
72cded9e SG |
18 | { |
19 | struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); | |
39c1fa2c DS |
20 | struct console_simple_priv *priv = dev_get_priv(dev); |
21 | struct video_fontdata *fontdata = priv->fontdata; | |
31547259 | 22 | void *line, *dst, *end; |
39c1fa2c | 23 | int pixels = fontdata->height * vid_priv->xsize; |
68f3fc76 | 24 | int ret; |
46421197 | 25 | int i; |
31547259 DS |
26 | int pbytes; |
27 | ||
28 | ret = check_bpix_support(vid_priv->bpix); | |
29 | if (ret) | |
30 | return ret; | |
72cded9e | 31 | |
39c1fa2c | 32 | line = vid_priv->fb + row * fontdata->height * vid_priv->line_length; |
31547259 DS |
33 | dst = line; |
34 | pbytes = VNBYTES(vid_priv->bpix); | |
35 | for (i = 0; i < pixels; i++) | |
36 | fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); | |
37 | end = dst; | |
38 | ||
68f3fc76 SG |
39 | ret = vidconsole_sync_copy(dev, line, end); |
40 | if (ret) | |
41 | return ret; | |
72cded9e SG |
42 | |
43 | return 0; | |
44 | } | |
45 | ||
31547259 DS |
46 | static int console_move_rows(struct udevice *dev, uint rowdst, |
47 | uint rowsrc, uint count) | |
72cded9e SG |
48 | { |
49 | struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); | |
39c1fa2c DS |
50 | struct console_simple_priv *priv = dev_get_priv(dev); |
51 | struct video_fontdata *fontdata = priv->fontdata; | |
72cded9e SG |
52 | void *dst; |
53 | void *src; | |
68f3fc76 SG |
54 | int size; |
55 | int ret; | |
72cded9e | 56 | |
39c1fa2c DS |
57 | dst = vid_priv->fb + rowdst * fontdata->height * vid_priv->line_length; |
58 | src = vid_priv->fb + rowsrc * fontdata->height * vid_priv->line_length; | |
59 | size = fontdata->height * vid_priv->line_length * count; | |
68f3fc76 SG |
60 | ret = vidconsole_memmove(dev, dst, src, size); |
61 | if (ret) | |
62 | return ret; | |
72cded9e SG |
63 | |
64 | return 0; | |
65 | } | |
66 | ||
5ea38f95 | 67 | static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp) |
72cded9e | 68 | { |
f2661786 | 69 | struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); |
72cded9e SG |
70 | struct udevice *vid = dev->parent; |
71 | struct video_priv *vid_priv = dev_get_uclass_priv(vid); | |
39c1fa2c DS |
72 | struct console_simple_priv *priv = dev_get_priv(dev); |
73 | struct video_fontdata *fontdata = priv->fontdata; | |
31547259 DS |
74 | int pbytes = VNBYTES(vid_priv->bpix); |
75 | int x, linenum, ret; | |
76 | void *start, *line; | |
5ea38f95 | 77 | u8 ch = console_utf_to_cp437(cp); |
39c1fa2c | 78 | uchar *pfont = fontdata->video_fontdata + |
5ea38f95 | 79 | ch * fontdata->char_pixel_bytes; |
68f3fc76 | 80 | |
31547259 DS |
81 | if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) |
82 | return -EAGAIN; | |
83 | linenum = y; | |
84 | x = VID_TO_PIXEL(x_frac); | |
85 | start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes; | |
68f3fc76 | 86 | line = start; |
f2661786 SG |
87 | |
88 | if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) | |
89 | return -EAGAIN; | |
72cded9e | 90 | |
39c1fa2c | 91 | ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION); |
31547259 DS |
92 | if (ret) |
93 | return ret; | |
94 | ||
68f3fc76 SG |
95 | ret = vidconsole_sync_copy(dev, start, line); |
96 | if (ret) | |
97 | return ret; | |
72cded9e | 98 | |
39c1fa2c | 99 | return VID_TO_POS(fontdata->width); |
f2661786 SG |
100 | } |
101 | ||
37db20d0 SG |
102 | static int console_set_cursor_visible(struct udevice *dev, bool visible, |
103 | uint x, uint y, uint index) | |
104 | { | |
105 | struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); | |
106 | struct udevice *vid = dev->parent; | |
107 | struct video_priv *vid_priv = dev_get_uclass_priv(vid); | |
108 | struct console_simple_priv *priv = dev_get_priv(dev); | |
109 | struct video_fontdata *fontdata = priv->fontdata; | |
110 | int pbytes = VNBYTES(vid_priv->bpix); | |
111 | void *start, *line; | |
112 | ||
113 | /* for now, this is not used outside expo */ | |
114 | if (!IS_ENABLED(CONFIG_EXPO)) | |
115 | return -ENOSYS; | |
116 | ||
117 | x += index * fontdata->width; | |
118 | start = vid_priv->fb + y * vid_priv->line_length + x * pbytes; | |
119 | ||
120 | /* place the cursor 1 pixel before the start of the next char */ | |
121 | x -= 1; | |
122 | ||
123 | line = start; | |
124 | draw_cursor_vertically(&line, vid_priv, vc_priv->y_charsize, | |
125 | NORMAL_DIRECTION); | |
126 | ||
127 | return 0; | |
128 | } | |
129 | ||
31547259 DS |
130 | struct vidconsole_ops console_ops = { |
131 | .putc_xy = console_putc_xy, | |
132 | .move_rows = console_move_rows, | |
133 | .set_row = console_set_row, | |
e7ee1fd5 DS |
134 | .get_font_size = console_simple_get_font_size, |
135 | .get_font = console_simple_get_font, | |
136 | .select_font = console_simple_select_font, | |
37db20d0 | 137 | .set_cursor_visible = console_set_cursor_visible, |
72cded9e SG |
138 | }; |
139 | ||
140 | U_BOOT_DRIVER(vidconsole_normal) = { | |
39c1fa2c DS |
141 | .name = "vidconsole0", |
142 | .id = UCLASS_VIDEO_CONSOLE, | |
143 | .ops = &console_ops, | |
144 | .probe = console_probe, | |
145 | .priv_auto = sizeof(struct console_simple_priv), | |
72cded9e | 146 | }; |