11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/drivers/video/console/sticon.c - console driver using HP's STI firmware 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002 Helge Deller <deller@gmx.de> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c, 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * which were 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Created 28 Sep 1997 by Geert Uytterhoeven 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Rewritten by Martin Mares <mj@ucw.cz>, July 1998 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1995 Jay Estabrook 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1995 Geert Uytterhoeven 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1993 Bjoern Brauel 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Roman Hodek 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1993 Hamish Macdonald 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Greg Harp 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk] 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with work by William Rucklidge (wjr@cs.cornell.edu) 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Geert Uytterhoeven 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Jes Sorensen (jds@kom.auc.dk) 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Martin Apel 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with work by Guenther Kelleter 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Martin Schaller 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Andreas Schwab 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Emmanuel Marty (core@ggi-project.org) 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Jakub Jelinek (jj@ultra.linux.cz) 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Martin Mares <mj@ucw.cz> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License. See the file COPYING in the main directory of this archive for 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * more details. 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/console.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/vt_kern.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kd.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/selection.h> 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "../sticore.h" 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* switching to graphics mode */ 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BLANK 0 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int vga_is_gfx; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this is the sti_struct used for this console */ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sti_struct *sticon_sti; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Software scrollback */ 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long softback_buf, softback_curr; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long softback_in; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long /* softback_top, */ softback_end; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int softback_lines; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* software cursor */ 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int cursor_drawn; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CURSOR_DRAW_DELAY (1) 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEFAULT_CURSOR_BLINK_RATE (20) 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int vbl_cursor_cnt; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void cursor_undrawn(void) 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vbl_cursor_cnt = 0; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor_drawn = 0; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 77b877a96409a3a99f2ce27b3c6473c9b28298ac7cAntonino A. Daplasstatic const char *sticon_startup(void) 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return "STI console"; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sticon_set_palette(struct vc_data *c, unsigned char *table) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int redraw_cursor = 0; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vga_is_gfx || console_blanked) 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (conp->vc_mode != KD_TEXT) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) { 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor_undrawn(); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds redraw_cursor = 1; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_putc(sticon_sti, c, ypos, xpos); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (redraw_cursor) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vbl_cursor_cnt = CURSOR_DRAW_DELAY; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_putcs(struct vc_data *conp, const unsigned short *s, 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int count, int ypos, int xpos) 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int redraw_cursor = 0; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vga_is_gfx || console_blanked) 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (conp->vc_mode != KD_TEXT) 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) && 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (p->cursor_x < (xpos + count))) { 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor_undrawn(); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds redraw_cursor = 1; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (count--) { 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (redraw_cursor) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vbl_cursor_cnt = CURSOR_DRAW_DELAY; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_cursor(struct vc_data *conp, int mode) 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short car1; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols]; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (mode) { 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CM_ERASE: 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CM_MOVE: 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CM_DRAW: 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (conp->vc_cursor_type & 0x0f) { 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_UNDERLINE: 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_LOWER_THIRD: 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_LOWER_HALF: 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_TWO_THIRDS: 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_BLOCK: 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds conp->vc_y, conp->vc_x); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count) 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sti_struct *sti = sticon_sti; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vga_is_gfx) 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sticon_cursor(conp, CM_ERASE); 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (dir) { 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SM_UP: 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); 17393f78da405685a756beeaeae4b5e41fcec39eab3Linus Torvalds sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SM_DOWN: 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); 17893f78da405685a756beeaeae4b5e41fcec39eab3Linus Torvalds sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_bmove(struct vc_data *conp, int sy, int sx, 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dy, int dx, int height, int width) 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!width || !height) 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) && 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (sx <= p->cursor_x) && (p->cursor_x < sx+width)) || 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((dy <= p->cursor_y) && (p->cursor_y < dy+height) && 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (dx <= p->cursor_x) && (p->cursor_x < dx+width))) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sticon_cursor(p, CM_ERASE /*|CM_SOFTBACK*/); 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_bmove(sticon_sti, sy, sx, dy, dx, height, width); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_init(struct vc_data *c, int init) 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sti_struct *sti = sticon_sti; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int vc_cols, vc_rows; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vc_cols = sti_onscreen_x(sti) / sti->font_width; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vc_rows = sti_onscreen_y(sti) / sti->font_height; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c->vc_can_do_color = 1; 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (init) { 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c->vc_cols = vc_cols; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c->vc_rows = vc_rows; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */ 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vc_resize(c, vc_cols, vc_rows); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* vc_resize_con(vc_rows, vc_cols, c->vc_num); */ 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_deinit(struct vc_data *c) 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_clear(struct vc_data *conp, int sy, int sx, int height, 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int width) 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!height || !width) 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sticon_switch(struct vc_data *conp) 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; /* needs refreshing */ 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sticon_set_origin(struct vc_data *conp) 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sticon_blank(struct vc_data *c, int blank, int mode_switch) 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (blank == 0) { 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode_switch) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vga_is_gfx = 0; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sticon_set_origin(c); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode_switch) 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vga_is_gfx = 1; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sticon_scrolldelta(struct vc_data *conp, int lines) 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u16 *sticon_screen_pos(struct vc_data *conp, int offset) 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int line; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long p; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (conp->vc_num != fg_console || !softback_lines) 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (u16 *)(conp->vc_origin + offset); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds line = offset / conp->vc_size_row; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (line >= softback_lines) 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = softback_curr + offset; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p >= softback_end) 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += softback_buf - softback_end; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (u16 *)p; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int *px, int *py) 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int x, y; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long ret; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos >= conp->vc_origin && pos < conp->vc_scr_end) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long offset = (pos - conp->vc_origin) / 2; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds x = offset % conp->vc_cols; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y = offset / conp->vc_cols; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (conp->vc_num == fg_console) 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y += softback_lines; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = pos + (conp->vc_cols - x) * 2; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (conp->vc_num == fg_console && softback_lines) { 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long offset = pos - softback_curr; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < softback_curr) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offset += softback_end - softback_buf; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offset /= 2; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds x = offset % conp->vc_cols; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y = offset / conp->vc_cols; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = pos + (conp->vc_cols - x) * 2; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret == softback_end) 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = softback_buf; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret == softback_in) 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = conp->vc_origin; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Should not happen */ 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds x = y = 0; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = conp->vc_origin; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (px) *px = x; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (py) *py = y; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, 317fa6ce9ab5fbcb4c276c48861584b70d387e787b3Jan Engelhardt u8 blink, u8 underline, u8 reverse, u8 italic) 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 attr = ((color & 0x70) >> 1) | ((color & 7)); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reverse) { 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds color = ((color >> 3) & 0x7) | ((color & 0x7) << 3); 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return attr; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_invert_region(struct vc_data *conp, u16 *p, int count) 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int col = 1; /* vga_can_do_color; */ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (count--) { 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 a = scr_readw(p); 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (col) 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a = ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scr_writew(a, p++); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sticon_save_screen(struct vc_data *conp) 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 348d95159cf1b12e8e4b169094b35cbd93b887cb939Helge Dellerstatic const struct consw sti_con = { 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_startup = sticon_startup, 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_init = sticon_init, 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_deinit = sticon_deinit, 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_clear = sticon_clear, 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_putc = sticon_putc, 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_putcs = sticon_putcs, 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_cursor = sticon_cursor, 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_scroll = sticon_scroll, 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_bmove = sticon_bmove, 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_switch = sticon_switch, 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_blank = sticon_blank, 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_set_palette = sticon_set_palette, 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_scrolldelta = sticon_scrolldelta, 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_set_origin = sticon_set_origin, 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_save_screen = sticon_save_screen, 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_build_attr = sticon_build_attr, 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_invert_region = sticon_invert_region, 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_screen_pos = sticon_screen_pos, 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .con_getxy = sticon_getxy, 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3733d1e412ac5570a669e1b1fc5fd0f6859250c3d76Adrian Bunkstatic int __init sticonsole_init(void) 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* already initialized ? */ 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sticon_sti) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sticon_sti = sti_get_rom(0); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sticon_sti) 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (conswitchp == &dummy_con) { 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "sticon: Initializing STI text console.\n"); 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(sticonsole_init); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 392