2 * linux/drivers/video/console/sticon.c - console driver using HP's STI firmware
4 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
5 * Copyright (C) 2002 Helge Deller <deller@gmx.de>
7 * Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
10 * Created 28 Sep 1997 by Geert Uytterhoeven
11 * Rewritten by Martin Mares <mj@ucw.cz>, July 1998
12 * Copyright (C) 1991, 1992 Linus Torvalds
14 * Copyright (C) 1995 Geert Uytterhoeven
15 * Copyright (C) 1993 Bjoern Brauel
17 * Copyright (C) 1993 Hamish Macdonald
19 * Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
21 * with work by William Rucklidge (wjr@cs.cornell.edu)
23 * Jes Sorensen (jds@kom.auc.dk)
25 * with work by Guenther Kelleter
28 * Emmanuel Marty (core@ggi-project.org)
29 * Jakub Jelinek (jj@ultra.linux.cz)
30 * Martin Mares <mj@ucw.cz>
32 * This file is subject to the terms and conditions of the GNU General Public
33 * License. See the file COPYING in the main directory of this archive for
38 #include <linux/init.h>
39 #include <linux/kernel.h>
40 #include <linux/tty.h>
41 #include <linux/console.h>
42 #include <linux/errno.h>
43 #include <linux/vt_kern.h>
45 #include <linux/selection.h>
46 #include <linux/module.h>
50 #include "../sticore.h"
52 /* switching to graphics mode */
54 static int vga_is_gfx
;
56 /* this is the sti_struct used for this console */
57 static struct sti_struct
*sticon_sti
;
59 /* Software scrollback */
60 static unsigned long softback_buf
, softback_curr
;
61 static unsigned long softback_in
;
62 static unsigned long /* softback_top, */ softback_end
;
63 static int softback_lines
;
66 static int cursor_drawn
;
67 #define CURSOR_DRAW_DELAY (1)
68 #define DEFAULT_CURSOR_BLINK_RATE (20)
70 static int vbl_cursor_cnt
;
72 static inline void cursor_undrawn(void)
78 static const char *__init
sticon_startup(void)
83 static int sticon_set_palette(struct vc_data
*c
, unsigned char *table
)
88 static int sticon_font_op(struct vc_data
*c
, struct console_font_op
*op
)
93 static void sticon_putc(struct vc_data
*conp
, int c
, int ypos
, int xpos
)
95 int unit
= conp
->vc_num
;
96 int redraw_cursor
= 0;
98 if (vga_is_gfx
|| console_blanked
)
101 if (vt_cons
[unit
]->vc_mode
!= KD_TEXT
)
104 if ((p
->cursor_x
== xpos
) && (p
->cursor_y
== ypos
)) {
110 sti_putc(sticon_sti
, c
, ypos
, xpos
);
113 vbl_cursor_cnt
= CURSOR_DRAW_DELAY
;
116 static void sticon_putcs(struct vc_data
*conp
, const unsigned short *s
,
117 int count
, int ypos
, int xpos
)
119 int unit
= conp
->vc_num
;
120 int redraw_cursor
= 0;
122 if (vga_is_gfx
|| console_blanked
)
125 if (vt_cons
[unit
]->vc_mode
!= KD_TEXT
)
129 if ((p
->cursor_y
== ypos
) && (xpos
<= p
->cursor_x
) &&
130 (p
->cursor_x
< (xpos
+ count
))) {
137 sti_putc(sticon_sti
, scr_readw(s
++), ypos
, xpos
++);
141 vbl_cursor_cnt
= CURSOR_DRAW_DELAY
;
144 static void sticon_cursor(struct vc_data
*conp
, int mode
)
148 car1
= conp
->vc_screenbuf
[conp
->vc_x
+ conp
->vc_y
* conp
->vc_cols
];
151 sti_putc(sticon_sti
, car1
, conp
->vc_y
, conp
->vc_x
);
155 switch (conp
->vc_cursor_type
& 0x0f) {
157 case CUR_LOWER_THIRD
:
161 sti_putc(sticon_sti
, (car1
& 255) + (0 << 8) + (7 << 11),
162 conp
->vc_y
, conp
->vc_x
);
169 static int sticon_scroll(struct vc_data
*conp
, int t
, int b
, int dir
, int count
)
171 struct sti_struct
*sti
= sticon_sti
;
176 sticon_cursor(conp
, CM_ERASE
);
180 sti_bmove(sti
, t
+ count
, 0, t
, 0, b
- t
- count
, conp
->vc_cols
);
181 sti_clear(sti
, b
- count
, 0, count
, conp
->vc_cols
, conp
->vc_video_erase_char
);
185 sti_bmove(sti
, t
, 0, t
+ count
, 0, b
- t
- count
, conp
->vc_cols
);
186 sti_clear(sti
, t
, 0, count
, conp
->vc_cols
, conp
->vc_video_erase_char
);
193 static void sticon_bmove(struct vc_data
*conp
, int sy
, int sx
,
194 int dy
, int dx
, int height
, int width
)
196 if (!width
|| !height
)
199 if (((sy
<= p
->cursor_y
) && (p
->cursor_y
< sy
+height
) &&
200 (sx
<= p
->cursor_x
) && (p
->cursor_x
< sx
+width
)) ||
201 ((dy
<= p
->cursor_y
) && (p
->cursor_y
< dy
+height
) &&
202 (dx
<= p
->cursor_x
) && (p
->cursor_x
< dx
+width
)))
203 sticon_cursor(p
, CM_ERASE
/*|CM_SOFTBACK*/);
206 sti_bmove(sticon_sti
, sy
, sx
, dy
, dx
, height
, width
);
209 static void sticon_init(struct vc_data
*c
, int init
)
211 struct sti_struct
*sti
= sticon_sti
;
212 int vc_cols
, vc_rows
;
214 sti_set(sti
, 0, 0, sti_onscreen_y(sti
), sti_onscreen_x(sti
), 0);
215 vc_cols
= sti_onscreen_x(sti
) / sti
->font_width
;
216 vc_rows
= sti_onscreen_y(sti
) / sti
->font_height
;
217 c
->vc_can_do_color
= 1;
220 c
->vc_cols
= vc_cols
;
221 c
->vc_rows
= vc_rows
;
223 /* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */
224 /* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */
225 vc_resize(c
->vc_num
, vc_cols
, vc_rows
);
226 /* vc_resize_con(vc_rows, vc_cols, c->vc_num); */
230 static void sticon_deinit(struct vc_data
*c
)
234 static void sticon_clear(struct vc_data
*conp
, int sy
, int sx
, int height
,
237 if (!height
|| !width
)
240 sti_clear(sticon_sti
, sy
, sx
, height
, width
, conp
->vc_video_erase_char
);
243 static int sticon_switch(struct vc_data
*conp
)
245 return 1; /* needs refreshing */
248 static int sticon_set_origin(struct vc_data
*conp
)
253 static int sticon_blank(struct vc_data
*c
, int blank
)
256 case 0: /* unblank */
258 /* Tell console.c that it has to restore the screen itself */
260 case 1: /* normal blanking */
261 default: /* VESA blanking */
264 sticon_set_origin(c
);
265 sti_clear(sticon_sti
, 0,0, c
->vc_rows
, c
->vc_cols
, BLANK
);
267 case -1: /* Entering graphic mode */
268 sti_clear(sticon_sti
, 0,0, c
->vc_rows
, c
->vc_cols
, BLANK
);
272 return 1; /* console needs to restore screen itself */
275 static int sticon_scrolldelta(struct vc_data
*conp
, int lines
)
280 static u16
*sticon_screen_pos(struct vc_data
*conp
, int offset
)
285 if (conp
->vc_num
!= fg_console
|| !softback_lines
)
286 return (u16
*)(conp
->vc_origin
+ offset
);
287 line
= offset
/ conp
->vc_size_row
;
288 if (line
>= softback_lines
)
289 return (u16
*)(conp
->vc_origin
+ offset
- softback_lines
* conp
->vc_size_row
);
290 p
= softback_curr
+ offset
;
291 if (p
>= softback_end
)
292 p
+= softback_buf
- softback_end
;
296 static unsigned long sticon_getxy(struct vc_data
*conp
, unsigned long pos
,
301 if (pos
>= conp
->vc_origin
&& pos
< conp
->vc_scr_end
) {
302 unsigned long offset
= (pos
- conp
->vc_origin
) / 2;
304 x
= offset
% conp
->vc_cols
;
305 y
= offset
/ conp
->vc_cols
;
306 if (conp
->vc_num
== fg_console
)
308 ret
= pos
+ (conp
->vc_cols
- x
) * 2;
309 } else if (conp
->vc_num
== fg_console
&& softback_lines
) {
310 unsigned long offset
= pos
- softback_curr
;
312 if (pos
< softback_curr
)
313 offset
+= softback_end
- softback_buf
;
315 x
= offset
% conp
->vc_cols
;
316 y
= offset
/ conp
->vc_cols
;
317 ret
= pos
+ (conp
->vc_cols
- x
) * 2;
318 if (ret
== softback_end
)
320 if (ret
== softback_in
)
321 ret
= conp
->vc_origin
;
323 /* Should not happen */
325 ret
= conp
->vc_origin
;
332 static u8
sticon_build_attr(struct vc_data
*conp
, u8 color
, u8 intens
,
333 u8 blink
, u8 underline
, u8 reverse
)
335 u8 attr
= ((color
& 0x70) >> 1) | ((color
& 7));
338 color
= ((color
>> 3) & 0x7) | ((color
& 0x7) << 3);
344 static void sticon_invert_region(struct vc_data
*conp
, u16
*p
, int count
)
346 int col
= 1; /* vga_can_do_color; */
349 u16 a
= scr_readw(p
);
352 a
= ((a
) & 0x88ff) | (((a
) & 0x7000) >> 4) | (((a
) & 0x0700) << 4);
354 a
= ((a
& 0x0700) == 0x0100) ? 0x7000 : 0x7700;
360 static void sticon_save_screen(struct vc_data
*conp
)
364 static struct consw sti_con
= {
365 .con_startup
= sticon_startup
,
366 .con_init
= sticon_init
,
367 .con_deinit
= sticon_deinit
,
368 .con_clear
= sticon_clear
,
369 .con_putc
= sticon_putc
,
370 .con_putcs
= sticon_putcs
,
371 .con_cursor
= sticon_cursor
,
372 .con_scroll
= sticon_scroll
,
373 .con_bmove
= sticon_bmove
,
374 .con_switch
= sticon_switch
,
375 .con_blank
= sticon_blank
,
376 .con_font_op
= sticon_font_op
,
377 .con_set_palette
= sticon_set_palette
,
378 .con_scrolldelta
= sticon_scrolldelta
,
379 .con_set_origin
= sticon_set_origin
,
380 .con_save_screen
= sticon_save_screen
,
381 .con_build_attr
= sticon_build_attr
,
382 .con_invert_region
= sticon_invert_region
,
383 .con_screen_pos
= sticon_screen_pos
,
384 .con_getxy
= sticon_getxy
,
389 int __init
sticonsole_init(void)
391 /* already initialized ? */
395 sticon_sti
= sti_get_rom(0);
399 if (conswitchp
== &dummy_con
) {
400 printk(KERN_INFO
"sticon: Initializing STI text console.\n");
401 take_over_console(&sti_con
, 0, MAX_NR_CONSOLES
- 1, 1);
406 module_init(sticonsole_init
);
407 MODULE_LICENSE("GPL");