Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: sisusbvga: remove console support

It was marked as BROKEN since commit 862ee699fefe (USB: sisusbvga: Make
console support depend on BROKEN) 2 years ago. Since noone stepped up to
fix it, remove it completely.

Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-sh@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20221208090749.28056-1-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jiri Slaby (SUSE) and committed by
Greg Kroah-Hartman
74d58cd4 1524ceb1

+6 -2959
-1
arch/powerpc/configs/ppc6xx_defconfig
··· 912 912 CONFIG_USB_FTDI_ELAN=m 913 913 CONFIG_USB_APPLEDISPLAY=m 914 914 CONFIG_USB_SISUSBVGA=m 915 - CONFIG_USB_SISUSBVGA_CON=y 916 915 CONFIG_USB_LD=m 917 916 CONFIG_USB_TRANCEVIBRATOR=m 918 917 CONFIG_USB_IOWARRIOR=m
-1
arch/sh/configs/landisk_defconfig
··· 92 92 CONFIG_USB_EMI62=m 93 93 CONFIG_USB_EMI26=m 94 94 CONFIG_USB_SISUSBVGA=m 95 - CONFIG_USB_SISUSBVGA_CON=y 96 95 CONFIG_EXT2_FS=y 97 96 CONFIG_EXT3_FS=y 98 97 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-34
drivers/usb/misc/sisusbvga/Kconfig
··· 3 3 config USB_SISUSBVGA 4 4 tristate "USB 2.0 SVGA dongle support (Net2280/SiS315)" 5 5 depends on (USB_MUSB_HDRC || USB_EHCI_HCD) 6 - select FONT_SUPPORT if USB_SISUSBVGA_CON 7 6 help 8 7 Say Y here if you intend to attach a USB2VGA dongle based on a 9 8 Net2280 and a SiS315 chip. ··· 12 13 13 14 To compile this driver as a module, choose M here; the module will be 14 15 called sisusbvga. If unsure, say N. 15 - 16 - config USB_SISUSBVGA_CON 17 - bool "Text console and mode switching support" if USB_SISUSBVGA 18 - depends on VT && BROKEN 19 - select FONT_8x16 20 - help 21 - Say Y here if you want a VGA text console via the USB dongle or 22 - want to support userland applications that utilize the driver's 23 - display mode switching capabilities. 24 - 25 - Note that this console supports VGA/EGA text mode only. 26 - 27 - By default, the console part of the driver will not kick in when 28 - the driver is initialized. If you want the driver to take over 29 - one or more of the consoles, you need to specify the number of 30 - the first and last consoles (starting at 1) as driver parameters. 31 - 32 - For example, if the driver is compiled as a module: 33 - 34 - modprobe sisusbvga first=1 last=5 35 - 36 - If you use hotplug, add this to your modutils config files with 37 - the "options" keyword, such as eg. 38 - 39 - options sisusbvga first=1 last=5 40 - 41 - If the driver is compiled into the kernel image, the parameters 42 - must be given in the kernel command like, such as 43 - 44 - sisusbvga.first=1 sisusbvga.last=5 45 - 46 - 47 -
-1
drivers/usb/misc/sisusbvga/Makefile
··· 6 6 obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga.o 7 7 8 8 sisusbvga-y := sisusb.o 9 - sisusbvga-$(CONFIG_USB_SISUSBVGA_CON) += sisusb_con.o sisusb_init.o
+6 -270
drivers/usb/misc/sisusbvga/sisusb.c
··· 51 51 #include <linux/vmalloc.h> 52 52 53 53 #include "sisusb.h" 54 - #include "sisusb_init.h" 55 - 56 - #ifdef CONFIG_USB_SISUSBVGA_CON 57 - #include <linux/font.h> 58 - #endif 59 54 60 55 #define SISUSB_DONTSYNC 61 56 62 57 /* Forward declarations / clean-up routines */ 63 - 64 - #ifdef CONFIG_USB_SISUSBVGA_CON 65 - static int sisusb_first_vc; 66 - static int sisusb_last_vc; 67 - module_param_named(first, sisusb_first_vc, int, 0); 68 - module_param_named(last, sisusb_last_vc, int, 0); 69 - MODULE_PARM_DESC(first, "Number of first console to take over (1 - MAX_NR_CONSOLES)"); 70 - MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES)"); 71 - #endif 72 58 73 59 static struct usb_driver sisusb_driver; 74 60 ··· 1184 1198 1185 1199 /* High level: Gfx (indexed) register access */ 1186 1200 1187 - #ifdef CONFIG_USB_SISUSBVGA_CON 1188 - int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data) 1189 - { 1190 - return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); 1191 - } 1192 - 1193 - int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 *data) 1194 - { 1195 - return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); 1196 - } 1197 - #endif 1198 - 1199 - int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, 1201 + static int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, 1200 1202 u8 index, u8 data) 1201 1203 { 1202 1204 int ret; ··· 1194 1220 return ret; 1195 1221 } 1196 1222 1197 - int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, 1223 + static int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, 1198 1224 u8 index, u8 *data) 1199 1225 { 1200 1226 int ret; ··· 1204 1230 return ret; 1205 1231 } 1206 1232 1207 - int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx, 1233 + static int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx, 1208 1234 u8 myand, u8 myor) 1209 1235 { 1210 1236 int ret; ··· 1232 1258 return ret; 1233 1259 } 1234 1260 1235 - int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, 1261 + static int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, 1236 1262 u8 index, u8 myor) 1237 1263 { 1238 1264 return sisusb_setidxregandor(sisusb, port, index, 0xff, myor); 1239 1265 } 1240 1266 1241 - int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, 1267 + static int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, 1242 1268 u8 idx, u8 myand) 1243 1269 { 1244 1270 return sisusb_setidxregandor(sisusb, port, idx, myand, 0x00); 1245 1271 } 1246 1272 1247 1273 /* Write/read video ram */ 1248 - 1249 - #ifdef CONFIG_USB_SISUSBVGA_CON 1250 - int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data) 1251 - { 1252 - return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data); 1253 - } 1254 - 1255 - int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data) 1256 - { 1257 - return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data); 1258 - } 1259 - 1260 - int sisusb_copy_memory(struct sisusb_usb_data *sisusb, u8 *src, 1261 - u32 dest, int length) 1262 - { 1263 - size_t dummy; 1264 - 1265 - return sisusb_write_mem_bulk(sisusb, dest, src, length, 1266 - NULL, 0, &dummy); 1267 - } 1268 - 1269 - #ifdef SISUSBENDIANTEST 1270 - static int sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest, 1271 - u32 src, int length) 1272 - { 1273 - size_t dummy; 1274 - 1275 - return sisusb_read_mem_bulk(sisusb, src, dest, length, 1276 - NULL, &dummy); 1277 - } 1278 - #endif 1279 - #endif 1280 1274 1281 1275 #ifdef SISUSBENDIANTEST 1282 1276 static void sisusb_testreadwrite(struct sisusb_usb_data *sisusb) ··· 2194 2252 return ret; 2195 2253 } 2196 2254 2197 - 2198 - #ifdef CONFIG_USB_SISUSBVGA_CON 2199 - 2200 - /* Set up default text mode: 2201 - * - Set text mode (0x03) 2202 - * - Upload default font 2203 - * - Upload user font (if available) 2204 - */ 2205 - 2206 - int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) 2207 - { 2208 - int ret = 0, slot = sisusb->font_slot, i; 2209 - const struct font_desc *myfont; 2210 - u8 *tempbuf; 2211 - u16 *tempbufb; 2212 - static const char bootstring[] = 2213 - "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; 2214 - static const char bootlogo[] = "(o_ //\\ V_/_"; 2215 - 2216 - /* sisusb->lock is down */ 2217 - 2218 - if (!sisusb->SiS_Pr) 2219 - return 1; 2220 - 2221 - sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30; 2222 - sisusb->SiS_Pr->sisusb = (void *)sisusb; 2223 - 2224 - /* Set mode 0x03 */ 2225 - SiSUSBSetMode(sisusb->SiS_Pr, 0x03); 2226 - 2227 - myfont = find_font("VGA8x16"); 2228 - if (!myfont) 2229 - return 1; 2230 - 2231 - tempbuf = vmalloc(8192); 2232 - if (!tempbuf) 2233 - return 1; 2234 - 2235 - for (i = 0; i < 256; i++) 2236 - memcpy(tempbuf + (i * 32), myfont->data + (i * 16), 16); 2237 - 2238 - /* Upload default font */ 2239 - ret = sisusbcon_do_font_op(sisusb, 1, 0, tempbuf, 8192, 2240 - 0, 1, NULL, 16, 0); 2241 - 2242 - vfree(tempbuf); 2243 - 2244 - /* Upload user font (and reset current slot) */ 2245 - if (sisusb->font_backup) { 2246 - ret |= sisusbcon_do_font_op(sisusb, 1, 2, sisusb->font_backup, 2247 - 8192, sisusb->font_backup_512, 1, NULL, 2248 - sisusb->font_backup_height, 0); 2249 - if (slot != 2) 2250 - sisusbcon_do_font_op(sisusb, 1, 0, NULL, 0, 0, 1, 2251 - NULL, 16, 0); 2252 - } 2253 - 2254 - if (init && !sisusb->scrbuf) { 2255 - 2256 - tempbuf = vmalloc(8192); 2257 - if (tempbuf) { 2258 - 2259 - i = 4096; 2260 - tempbufb = (u16 *)tempbuf; 2261 - while (i--) 2262 - *(tempbufb++) = 0x0720; 2263 - 2264 - i = 0; 2265 - tempbufb = (u16 *)tempbuf; 2266 - while (bootlogo[i]) { 2267 - *(tempbufb++) = 0x0700 | bootlogo[i++]; 2268 - if (!(i % 4)) 2269 - tempbufb += 76; 2270 - } 2271 - 2272 - i = 0; 2273 - tempbufb = (u16 *)tempbuf + 6; 2274 - while (bootstring[i]) 2275 - *(tempbufb++) = 0x0700 | bootstring[i++]; 2276 - 2277 - ret |= sisusb_copy_memory(sisusb, tempbuf, 2278 - sisusb->vrambase, 8192); 2279 - 2280 - vfree(tempbuf); 2281 - 2282 - } 2283 - 2284 - } else if (sisusb->scrbuf) { 2285 - ret |= sisusb_copy_memory(sisusb, (u8 *)sisusb->scrbuf, 2286 - sisusb->vrambase, sisusb->scrbuf_size); 2287 - } 2288 - 2289 - if (sisusb->sisusb_cursor_size_from >= 0 && 2290 - sisusb->sisusb_cursor_size_to >= 0) { 2291 - sisusb_setidxreg(sisusb, SISCR, 0x0a, 2292 - sisusb->sisusb_cursor_size_from); 2293 - sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0, 2294 - sisusb->sisusb_cursor_size_to); 2295 - } else { 2296 - sisusb_setidxreg(sisusb, SISCR, 0x0a, 0x2d); 2297 - sisusb_setidxreg(sisusb, SISCR, 0x0b, 0x0e); 2298 - sisusb->sisusb_cursor_size_to = -1; 2299 - } 2300 - 2301 - slot = sisusb->sisusb_cursor_loc; 2302 - if (slot < 0) 2303 - slot = 0; 2304 - 2305 - sisusb->sisusb_cursor_loc = -1; 2306 - sisusb->bad_cursor_pos = 1; 2307 - 2308 - sisusb_set_cursor(sisusb, slot); 2309 - 2310 - sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8)); 2311 - sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff)); 2312 - 2313 - sisusb->textmodedestroyed = 0; 2314 - 2315 - /* sisusb->lock is down */ 2316 - 2317 - return ret; 2318 - } 2319 - 2320 - #endif 2321 - 2322 2255 /* fops */ 2323 2256 2324 2257 static int sisusb_open(struct inode *inode, struct file *file) ··· 2251 2434 return 0; 2252 2435 } 2253 2436 2254 - void sisusb_delete(struct kref *kref) 2437 + static void sisusb_delete(struct kref *kref) 2255 2438 { 2256 2439 struct sisusb_usb_data *sisusb = to_sisusb_dev(kref); 2257 2440 ··· 2263 2446 sisusb->sisusb_dev = NULL; 2264 2447 sisusb_free_buffers(sisusb); 2265 2448 sisusb_free_urbs(sisusb); 2266 - #ifdef CONFIG_USB_SISUSBVGA_CON 2267 - kfree(sisusb->SiS_Pr); 2268 - #endif 2269 2449 kfree(sisusb); 2270 2450 } 2271 2451 ··· 2656 2842 2657 2843 case SUCMD_HANDLETEXTMODE: 2658 2844 retval = 0; 2659 - #ifdef CONFIG_USB_SISUSBVGA_CON 2660 - /* Gfx core must be initialized, SiS_Pr must exist */ 2661 - if (!sisusb->gfxinit || !sisusb->SiS_Pr) 2662 - return -ENODEV; 2663 - 2664 - switch (y->data0) { 2665 - case 0: 2666 - retval = sisusb_reset_text_mode(sisusb, 0); 2667 - break; 2668 - case 1: 2669 - sisusb->textmodedestroyed = 1; 2670 - break; 2671 - } 2672 - #endif 2673 2845 break; 2674 - 2675 - #ifdef CONFIG_USB_SISUSBVGA_CON 2676 - case SUCMD_SETMODE: 2677 - /* Gfx core must be initialized, SiS_Pr must exist */ 2678 - if (!sisusb->gfxinit || !sisusb->SiS_Pr) 2679 - return -ENODEV; 2680 - 2681 - retval = 0; 2682 - 2683 - sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30; 2684 - sisusb->SiS_Pr->sisusb = (void *)sisusb; 2685 - 2686 - if (SiSUSBSetMode(sisusb->SiS_Pr, y->data3)) 2687 - retval = -EINVAL; 2688 - 2689 - break; 2690 - 2691 - case SUCMD_SETVESAMODE: 2692 - /* Gfx core must be initialized, SiS_Pr must exist */ 2693 - if (!sisusb->gfxinit || !sisusb->SiS_Pr) 2694 - return -ENODEV; 2695 - 2696 - retval = 0; 2697 - 2698 - sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30; 2699 - sisusb->SiS_Pr->sisusb = (void *)sisusb; 2700 - 2701 - if (SiSUSBSetVESAMode(sisusb->SiS_Pr, y->data3)) 2702 - retval = -EINVAL; 2703 - 2704 - break; 2705 - #endif 2706 2846 2707 2847 default: 2708 2848 retval = -EINVAL; ··· 2710 2942 x.sisusb_vramsize = sisusb->vramsize; 2711 2943 x.sisusb_minor = sisusb->minor; 2712 2944 x.sisusb_fbdevactive = 0; 2713 - #ifdef CONFIG_USB_SISUSBVGA_CON 2714 - x.sisusb_conactive = sisusb->haveconsole ? 1 : 0; 2715 - #else 2716 2945 x.sisusb_conactive = 0; 2717 - #endif 2718 2946 memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved)); 2719 2947 2720 2948 if (copy_to_user((void __user *)arg, &x, sizeof(x))) ··· 2854 3090 dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", 2855 3091 sisusb->numobufs); 2856 3092 2857 - #ifdef CONFIG_USB_SISUSBVGA_CON 2858 - /* Allocate our SiS_Pr */ 2859 - sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL); 2860 - if (!sisusb->SiS_Pr) { 2861 - retval = -ENOMEM; 2862 - goto error_4; 2863 - } 2864 - #endif 2865 - 2866 3093 /* Do remaining init stuff */ 2867 3094 2868 3095 init_waitqueue_head(&sisusb->wait_q); ··· 2866 3111 2867 3112 if (dev->speed == USB_SPEED_HIGH || dev->speed >= USB_SPEED_SUPER) { 2868 3113 int initscreen = 1; 2869 - #ifdef CONFIG_USB_SISUSBVGA_CON 2870 - if (sisusb_first_vc > 0 && sisusb_last_vc > 0 && 2871 - sisusb_first_vc <= sisusb_last_vc && 2872 - sisusb_last_vc <= MAX_NR_CONSOLES) 2873 - initscreen = 0; 2874 - #endif 2875 3114 if (sisusb_init_gfxdevice(sisusb, initscreen)) 2876 3115 dev_err(&sisusb->sisusb_dev->dev, 2877 3116 "Failed to early initialize device\n"); ··· 2880 3131 dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST ***\n"); 2881 3132 sisusb_testreadwrite(sisusb); 2882 3133 dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n"); 2883 - #endif 2884 - 2885 - #ifdef CONFIG_USB_SISUSBVGA_CON 2886 - sisusb_console_init(sisusb, sisusb_first_vc, sisusb_last_vc); 2887 3134 #endif 2888 3135 2889 3136 return 0; ··· 2903 3158 sisusb = usb_get_intfdata(intf); 2904 3159 if (!sisusb) 2905 3160 return; 2906 - 2907 - #ifdef CONFIG_USB_SISUSBVGA_CON 2908 - sisusb_console_exit(sisusb); 2909 - #endif 2910 3161 2911 3162 usb_deregister_dev(intf, &usb_sisusb_class); 2912 3163 ··· 2949 3208 2950 3209 static int __init usb_sisusb_init(void) 2951 3210 { 2952 - 2953 - #ifdef CONFIG_USB_SISUSBVGA_CON 2954 - sisusb_init_concode(); 2955 - #endif 2956 - 2957 3211 return usb_register(&sisusb_driver); 2958 3212 } 2959 3213
-21
drivers/usb/misc/sisusbvga/sisusb.h
··· 48 48 49 49 /* Include console and mode switching code? */ 50 50 51 - #include <linux/console.h> 52 51 #include <linux/vt_kern.h> 53 52 #include "sisusb_struct.h" 54 53 ··· 125 126 unsigned char gfxinit; /* graphics core initialized? */ 126 127 unsigned short chipid, chipvendor; 127 128 unsigned short chiprevision; 128 - #ifdef CONFIG_USB_SISUSBVGA_CON 129 - struct SiS_Private *SiS_Pr; 130 - unsigned long scrbuf; 131 - unsigned int scrbuf_size; 132 - int haveconsole, con_first, con_last; 133 - int havethisconsole[MAX_NR_CONSOLES]; 134 - int textmodedestroyed; 135 - unsigned int sisusb_num_columns; /* real number, not vt's idea */ 136 - int cur_start_addr, con_rolled_over; 137 - int sisusb_cursor_loc, bad_cursor_pos; 138 - int sisusb_cursor_size_from; 139 - int sisusb_cursor_size_to; 140 - int current_font_height, current_font_512; 141 - int font_backup_size, font_backup_height, font_backup_512; 142 - char *font_backup; 143 - int font_slot; 144 - struct vc_data *sisusb_display_fg; 145 - int is_gfx; 146 - int con_blanked; 147 - #endif 148 129 }; 149 130 150 131 #define to_sisusb_dev(d) container_of(d, struct sisusb_usb_data, kref)
-1496
drivers/usb/misc/sisusbvga/sisusb_con.c
··· 1 - // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 - /* 3 - * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles 4 - * 5 - * VGA text mode console part 6 - * 7 - * Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria 8 - * 9 - * If distributed as part of the Linux kernel, this code is licensed under the 10 - * terms of the GPL v2. 11 - * 12 - * Otherwise, the following license terms apply: 13 - * 14 - * * Redistribution and use in source and binary forms, with or without 15 - * * modification, are permitted provided that the following conditions 16 - * * are met: 17 - * * 1) Redistributions of source code must retain the above copyright 18 - * * notice, this list of conditions and the following disclaimer. 19 - * * 2) Redistributions in binary form must reproduce the above copyright 20 - * * notice, this list of conditions and the following disclaimer in the 21 - * * documentation and/or other materials provided with the distribution. 22 - * * 3) The name of the author may not be used to endorse or promote products 23 - * * derived from this software without specific psisusbr written permission. 24 - * * 25 - * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR 26 - * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 - * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 - * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 - * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 - * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 - * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 - * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 - * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 - * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 - * 36 - * Author: Thomas Winischhofer <thomas@winischhofer.net> 37 - * 38 - * Portions based on vgacon.c which are 39 - * Created 28 Sep 1997 by Geert Uytterhoeven 40 - * Rewritten by Martin Mares <mj@ucw.cz>, July 1998 41 - * based on code Copyright (C) 1991, 1992 Linus Torvalds 42 - * 1995 Jay Estabrook 43 - * 44 - * A note on using in_atomic() in here: We can't handle console 45 - * calls from non-schedulable context due to our USB-dependend 46 - * nature. For now, this driver just ignores any calls if it 47 - * detects this state. 48 - * 49 - */ 50 - 51 - #include <linux/mutex.h> 52 - #include <linux/module.h> 53 - #include <linux/kernel.h> 54 - #include <linux/signal.h> 55 - #include <linux/fs.h> 56 - #include <linux/usb.h> 57 - #include <linux/tty.h> 58 - #include <linux/console.h> 59 - #include <linux/string.h> 60 - #include <linux/kd.h> 61 - #include <linux/init.h> 62 - #include <linux/vt_kern.h> 63 - #include <linux/selection.h> 64 - #include <linux/spinlock.h> 65 - #include <linux/kref.h> 66 - #include <linux/ioport.h> 67 - #include <linux/interrupt.h> 68 - #include <linux/vmalloc.h> 69 - 70 - #include "sisusb.h" 71 - #include "sisusb_init.h" 72 - 73 - /* vc_data -> sisusb conversion table */ 74 - static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES]; 75 - 76 - /* Forward declaration */ 77 - static const struct consw sisusb_con; 78 - 79 - static inline void 80 - sisusbcon_memsetw(u16 *s, u16 c, unsigned int count) 81 - { 82 - memset16(s, c, count / 2); 83 - } 84 - 85 - static inline void 86 - sisusb_initialize(struct sisusb_usb_data *sisusb) 87 - { 88 - /* Reset cursor and start address */ 89 - if (sisusb_setidxreg(sisusb, SISCR, 0x0c, 0x00)) 90 - return; 91 - if (sisusb_setidxreg(sisusb, SISCR, 0x0d, 0x00)) 92 - return; 93 - if (sisusb_setidxreg(sisusb, SISCR, 0x0e, 0x00)) 94 - return; 95 - sisusb_setidxreg(sisusb, SISCR, 0x0f, 0x00); 96 - } 97 - 98 - static inline void 99 - sisusbcon_set_start_address(struct sisusb_usb_data *sisusb, struct vc_data *c) 100 - { 101 - sisusb->cur_start_addr = (c->vc_visible_origin - sisusb->scrbuf) / 2; 102 - 103 - sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8)); 104 - sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff)); 105 - } 106 - 107 - void 108 - sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location) 109 - { 110 - if (sisusb->sisusb_cursor_loc == location) 111 - return; 112 - 113 - sisusb->sisusb_cursor_loc = location; 114 - 115 - /* Hardware bug: Text cursor appears twice or not at all 116 - * at some positions. Work around it with the cursor skew 117 - * bits. 118 - */ 119 - 120 - if ((location & 0x0007) == 0x0007) { 121 - sisusb->bad_cursor_pos = 1; 122 - location--; 123 - if (sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0x1f, 0x20)) 124 - return; 125 - } else if (sisusb->bad_cursor_pos) { 126 - if (sisusb_setidxregand(sisusb, SISCR, 0x0b, 0x1f)) 127 - return; 128 - sisusb->bad_cursor_pos = 0; 129 - } 130 - 131 - if (sisusb_setidxreg(sisusb, SISCR, 0x0e, (location >> 8))) 132 - return; 133 - sisusb_setidxreg(sisusb, SISCR, 0x0f, (location & 0xff)); 134 - } 135 - 136 - static inline struct sisusb_usb_data * 137 - sisusb_get_sisusb(unsigned short console) 138 - { 139 - return mysisusbs[console]; 140 - } 141 - 142 - static inline int 143 - sisusb_sisusb_valid(struct sisusb_usb_data *sisusb) 144 - { 145 - if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) 146 - return 0; 147 - 148 - return 1; 149 - } 150 - 151 - static struct sisusb_usb_data * 152 - sisusb_get_sisusb_lock_and_check(unsigned short console) 153 - { 154 - struct sisusb_usb_data *sisusb; 155 - 156 - /* We can't handle console calls in non-schedulable 157 - * context due to our locks and the USB transport. 158 - * So we simply ignore them. This should only affect 159 - * some calls to printk. 160 - */ 161 - if (in_atomic()) 162 - return NULL; 163 - 164 - sisusb = sisusb_get_sisusb(console); 165 - if (!sisusb) 166 - return NULL; 167 - 168 - mutex_lock(&sisusb->lock); 169 - 170 - if (!sisusb_sisusb_valid(sisusb) || 171 - !sisusb->havethisconsole[console]) { 172 - mutex_unlock(&sisusb->lock); 173 - return NULL; 174 - } 175 - 176 - return sisusb; 177 - } 178 - 179 - static int 180 - sisusb_is_inactive(struct vc_data *c, struct sisusb_usb_data *sisusb) 181 - { 182 - if (sisusb->is_gfx || 183 - sisusb->textmodedestroyed || 184 - c->vc_mode != KD_TEXT) 185 - return 1; 186 - 187 - return 0; 188 - } 189 - 190 - /* con_startup console interface routine */ 191 - static const char * 192 - sisusbcon_startup(void) 193 - { 194 - return "SISUSBCON"; 195 - } 196 - 197 - /* con_init console interface routine */ 198 - static void 199 - sisusbcon_init(struct vc_data *c, int init) 200 - { 201 - struct sisusb_usb_data *sisusb; 202 - int cols, rows; 203 - 204 - /* This is called by do_take_over_console(), 205 - * ie by us/under our control. It is 206 - * only called after text mode and fonts 207 - * are set up/restored. 208 - */ 209 - 210 - sisusb = sisusb_get_sisusb(c->vc_num); 211 - if (!sisusb) 212 - return; 213 - 214 - mutex_lock(&sisusb->lock); 215 - 216 - if (!sisusb_sisusb_valid(sisusb)) { 217 - mutex_unlock(&sisusb->lock); 218 - return; 219 - } 220 - 221 - c->vc_can_do_color = 1; 222 - 223 - c->vc_complement_mask = 0x7700; 224 - 225 - c->vc_hi_font_mask = sisusb->current_font_512 ? 0x0800 : 0; 226 - 227 - sisusb->haveconsole = 1; 228 - 229 - sisusb->havethisconsole[c->vc_num] = 1; 230 - 231 - /* We only support 640x400 */ 232 - c->vc_scan_lines = 400; 233 - 234 - c->vc_font.height = sisusb->current_font_height; 235 - 236 - /* We only support width = 8 */ 237 - cols = 80; 238 - rows = c->vc_scan_lines / c->vc_font.height; 239 - 240 - /* Increment usage count for our sisusb. 241 - * Doing so saves us from upping/downing 242 - * the disconnect semaphore; we can't 243 - * lose our sisusb until this is undone 244 - * in con_deinit. For all other console 245 - * interface functions, it suffices to 246 - * use sisusb->lock and do a quick check 247 - * of sisusb for device disconnection. 248 - */ 249 - kref_get(&sisusb->kref); 250 - 251 - if (!*c->uni_pagedict_loc) 252 - con_set_default_unimap(c); 253 - 254 - mutex_unlock(&sisusb->lock); 255 - 256 - if (init) { 257 - c->vc_cols = cols; 258 - c->vc_rows = rows; 259 - } else 260 - vc_resize(c, cols, rows); 261 - } 262 - 263 - /* con_deinit console interface routine */ 264 - static void 265 - sisusbcon_deinit(struct vc_data *c) 266 - { 267 - struct sisusb_usb_data *sisusb; 268 - int i; 269 - 270 - /* This is called by do_take_over_console() 271 - * and others, ie not under our control. 272 - */ 273 - 274 - sisusb = sisusb_get_sisusb(c->vc_num); 275 - if (!sisusb) 276 - return; 277 - 278 - mutex_lock(&sisusb->lock); 279 - 280 - /* Clear ourselves in mysisusbs */ 281 - mysisusbs[c->vc_num] = NULL; 282 - 283 - sisusb->havethisconsole[c->vc_num] = 0; 284 - 285 - /* Free our font buffer if all consoles are gone */ 286 - if (sisusb->font_backup) { 287 - for(i = 0; i < MAX_NR_CONSOLES; i++) { 288 - if (sisusb->havethisconsole[c->vc_num]) 289 - break; 290 - } 291 - if (i == MAX_NR_CONSOLES) { 292 - vfree(sisusb->font_backup); 293 - sisusb->font_backup = NULL; 294 - } 295 - } 296 - 297 - mutex_unlock(&sisusb->lock); 298 - 299 - /* decrement the usage count on our sisusb */ 300 - kref_put(&sisusb->kref, sisusb_delete); 301 - } 302 - 303 - /* interface routine */ 304 - static u8 305 - sisusbcon_build_attr(struct vc_data *c, u8 color, enum vc_intensity intensity, 306 - bool blink, bool underline, bool reverse, 307 - bool unused) 308 - { 309 - u8 attr = color; 310 - 311 - if (underline) 312 - attr = (attr & 0xf0) | c->vc_ulcolor; 313 - else if (intensity == VCI_HALF_BRIGHT) 314 - attr = (attr & 0xf0) | c->vc_halfcolor; 315 - 316 - if (reverse) 317 - attr = ((attr) & 0x88) | 318 - ((((attr) >> 4) | 319 - ((attr) << 4)) & 0x77); 320 - 321 - if (blink) 322 - attr ^= 0x80; 323 - 324 - if (intensity == VCI_BOLD) 325 - attr ^= 0x08; 326 - 327 - return attr; 328 - } 329 - 330 - /* Interface routine */ 331 - static void 332 - sisusbcon_invert_region(struct vc_data *vc, u16 *p, int count) 333 - { 334 - /* Invert a region. This is called with a pointer 335 - * to the console's internal screen buffer. So we 336 - * simply do the inversion there and rely on 337 - * a call to putc(s) to update the real screen. 338 - */ 339 - 340 - while (count--) { 341 - u16 a = *p; 342 - 343 - *p++ = ((a) & 0x88ff) | 344 - (((a) & 0x7000) >> 4) | 345 - (((a) & 0x0700) << 4); 346 - } 347 - } 348 - 349 - static inline void *sisusb_vaddr(const struct sisusb_usb_data *sisusb, 350 - const struct vc_data *c, unsigned int x, unsigned int y) 351 - { 352 - return (u16 *)c->vc_origin + y * sisusb->sisusb_num_columns + x; 353 - } 354 - 355 - static inline unsigned long sisusb_haddr(const struct sisusb_usb_data *sisusb, 356 - const struct vc_data *c, unsigned int x, unsigned int y) 357 - { 358 - unsigned long offset = c->vc_origin - sisusb->scrbuf; 359 - 360 - /* 2 bytes per each character */ 361 - offset += 2 * (y * sisusb->sisusb_num_columns + x); 362 - 363 - return sisusb->vrambase + offset; 364 - } 365 - 366 - /* Interface routine */ 367 - static void 368 - sisusbcon_putc(struct vc_data *c, int ch, int y, int x) 369 - { 370 - struct sisusb_usb_data *sisusb; 371 - 372 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 373 - if (!sisusb) 374 - return; 375 - 376 - /* sisusb->lock is down */ 377 - if (sisusb_is_inactive(c, sisusb)) { 378 - mutex_unlock(&sisusb->lock); 379 - return; 380 - } 381 - 382 - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), 383 - sisusb_haddr(sisusb, c, x, y), 2); 384 - 385 - mutex_unlock(&sisusb->lock); 386 - } 387 - 388 - /* Interface routine */ 389 - static void 390 - sisusbcon_putcs(struct vc_data *c, const unsigned short *s, 391 - int count, int y, int x) 392 - { 393 - struct sisusb_usb_data *sisusb; 394 - 395 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 396 - if (!sisusb) 397 - return; 398 - 399 - /* sisusb->lock is down */ 400 - 401 - /* Need to put the characters into the buffer ourselves, 402 - * because the vt does this AFTER calling us. 403 - */ 404 - 405 - memcpy(sisusb_vaddr(sisusb, c, x, y), s, count * 2); 406 - 407 - if (sisusb_is_inactive(c, sisusb)) { 408 - mutex_unlock(&sisusb->lock); 409 - return; 410 - } 411 - 412 - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), 413 - sisusb_haddr(sisusb, c, x, y), count * 2); 414 - 415 - mutex_unlock(&sisusb->lock); 416 - } 417 - 418 - /* Interface routine */ 419 - static void 420 - sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) 421 - { 422 - struct sisusb_usb_data *sisusb; 423 - u16 eattr = c->vc_video_erase_char; 424 - int i, length, cols; 425 - u16 *dest; 426 - 427 - if (width <= 0 || height <= 0) 428 - return; 429 - 430 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 431 - if (!sisusb) 432 - return; 433 - 434 - /* sisusb->lock is down */ 435 - 436 - /* Need to clear buffer ourselves, because the vt does 437 - * this AFTER calling us. 438 - */ 439 - 440 - dest = sisusb_vaddr(sisusb, c, x, y); 441 - 442 - cols = sisusb->sisusb_num_columns; 443 - 444 - if (width > cols) 445 - width = cols; 446 - 447 - if (x == 0 && width >= c->vc_cols) { 448 - 449 - sisusbcon_memsetw(dest, eattr, height * cols * 2); 450 - 451 - } else { 452 - 453 - for (i = height; i > 0; i--, dest += cols) 454 - sisusbcon_memsetw(dest, eattr, width * 2); 455 - 456 - } 457 - 458 - if (sisusb_is_inactive(c, sisusb)) { 459 - mutex_unlock(&sisusb->lock); 460 - return; 461 - } 462 - 463 - length = ((height * cols) - x - (cols - width - x)) * 2; 464 - 465 - 466 - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), 467 - sisusb_haddr(sisusb, c, x, y), length); 468 - 469 - mutex_unlock(&sisusb->lock); 470 - } 471 - 472 - /* interface routine */ 473 - static int 474 - sisusbcon_switch(struct vc_data *c) 475 - { 476 - struct sisusb_usb_data *sisusb; 477 - int length; 478 - 479 - /* Returnvalue 0 means we have fully restored screen, 480 - * and vt doesn't need to call do_update_region(). 481 - * Returnvalue != 0 naturally means the opposite. 482 - */ 483 - 484 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 485 - if (!sisusb) 486 - return 0; 487 - 488 - /* sisusb->lock is down */ 489 - 490 - /* Don't write to screen if in gfx mode */ 491 - if (sisusb_is_inactive(c, sisusb)) { 492 - mutex_unlock(&sisusb->lock); 493 - return 0; 494 - } 495 - 496 - /* That really should not happen. It would mean we are 497 - * being called while the vc is using its private buffer 498 - * as origin. 499 - */ 500 - if (c->vc_origin == (unsigned long)c->vc_screenbuf) { 501 - mutex_unlock(&sisusb->lock); 502 - dev_dbg(&sisusb->sisusb_dev->dev, "ASSERT ORIGIN != SCREENBUF!\n"); 503 - return 0; 504 - } 505 - 506 - /* Check that we don't copy too much */ 507 - length = min((int)c->vc_screenbuf_size, 508 - (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); 509 - 510 - /* Restore the screen contents */ 511 - memcpy((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, length); 512 - 513 - sisusb_copy_memory(sisusb, (u8 *)c->vc_origin, 514 - sisusb_haddr(sisusb, c, 0, 0), length); 515 - 516 - mutex_unlock(&sisusb->lock); 517 - 518 - return 0; 519 - } 520 - 521 - /* interface routine */ 522 - static void 523 - sisusbcon_save_screen(struct vc_data *c) 524 - { 525 - struct sisusb_usb_data *sisusb; 526 - int length; 527 - 528 - /* Save the current screen contents to vc's private 529 - * buffer. 530 - */ 531 - 532 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 533 - if (!sisusb) 534 - return; 535 - 536 - /* sisusb->lock is down */ 537 - 538 - if (sisusb_is_inactive(c, sisusb)) { 539 - mutex_unlock(&sisusb->lock); 540 - return; 541 - } 542 - 543 - /* Check that we don't copy too much */ 544 - length = min((int)c->vc_screenbuf_size, 545 - (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); 546 - 547 - /* Save the screen contents to vc's private buffer */ 548 - memcpy((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, length); 549 - 550 - mutex_unlock(&sisusb->lock); 551 - } 552 - 553 - /* interface routine */ 554 - static void 555 - sisusbcon_set_palette(struct vc_data *c, const unsigned char *table) 556 - { 557 - struct sisusb_usb_data *sisusb; 558 - int i, j; 559 - 560 - /* Return value not used by vt */ 561 - 562 - if (!con_is_visible(c)) 563 - return; 564 - 565 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 566 - if (!sisusb) 567 - return; 568 - 569 - /* sisusb->lock is down */ 570 - 571 - if (sisusb_is_inactive(c, sisusb)) { 572 - mutex_unlock(&sisusb->lock); 573 - return; 574 - } 575 - 576 - for (i = j = 0; i < 16; i++) { 577 - if (sisusb_setreg(sisusb, SISCOLIDX, table[i])) 578 - break; 579 - if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) 580 - break; 581 - if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) 582 - break; 583 - if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) 584 - break; 585 - } 586 - 587 - mutex_unlock(&sisusb->lock); 588 - } 589 - 590 - /* interface routine */ 591 - static int 592 - sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) 593 - { 594 - struct sisusb_usb_data *sisusb; 595 - u8 sr1, cr17, pmreg, cr63; 596 - int ret = 0; 597 - 598 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 599 - if (!sisusb) 600 - return 0; 601 - 602 - /* sisusb->lock is down */ 603 - 604 - if (mode_switch) 605 - sisusb->is_gfx = blank ? 1 : 0; 606 - 607 - if (sisusb_is_inactive(c, sisusb)) { 608 - mutex_unlock(&sisusb->lock); 609 - return 0; 610 - } 611 - 612 - switch (blank) { 613 - 614 - case 1: /* Normal blanking: Clear screen */ 615 - case -1: 616 - sisusbcon_memsetw((u16 *)c->vc_origin, 617 - c->vc_video_erase_char, 618 - c->vc_screenbuf_size); 619 - sisusb_copy_memory(sisusb, (u8 *)c->vc_origin, 620 - sisusb_haddr(sisusb, c, 0, 0), 621 - c->vc_screenbuf_size); 622 - sisusb->con_blanked = 1; 623 - ret = 1; 624 - break; 625 - 626 - default: /* VESA blanking */ 627 - switch (blank) { 628 - case 0: /* Unblank */ 629 - sr1 = 0x00; 630 - cr17 = 0x80; 631 - pmreg = 0x00; 632 - cr63 = 0x00; 633 - ret = 1; 634 - sisusb->con_blanked = 0; 635 - break; 636 - case VESA_VSYNC_SUSPEND + 1: 637 - sr1 = 0x20; 638 - cr17 = 0x80; 639 - pmreg = 0x80; 640 - cr63 = 0x40; 641 - break; 642 - case VESA_HSYNC_SUSPEND + 1: 643 - sr1 = 0x20; 644 - cr17 = 0x80; 645 - pmreg = 0x40; 646 - cr63 = 0x40; 647 - break; 648 - case VESA_POWERDOWN + 1: 649 - sr1 = 0x20; 650 - cr17 = 0x00; 651 - pmreg = 0xc0; 652 - cr63 = 0x40; 653 - break; 654 - default: 655 - mutex_unlock(&sisusb->lock); 656 - return -EINVAL; 657 - } 658 - 659 - sisusb_setidxregandor(sisusb, SISSR, 0x01, ~0x20, sr1); 660 - sisusb_setidxregandor(sisusb, SISCR, 0x17, 0x7f, cr17); 661 - sisusb_setidxregandor(sisusb, SISSR, 0x1f, 0x3f, pmreg); 662 - sisusb_setidxregandor(sisusb, SISCR, 0x63, 0xbf, cr63); 663 - 664 - } 665 - 666 - mutex_unlock(&sisusb->lock); 667 - 668 - return ret; 669 - } 670 - 671 - /* interface routine */ 672 - static void 673 - sisusbcon_scrolldelta(struct vc_data *c, int lines) 674 - { 675 - struct sisusb_usb_data *sisusb; 676 - 677 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 678 - if (!sisusb) 679 - return; 680 - 681 - /* sisusb->lock is down */ 682 - 683 - if (sisusb_is_inactive(c, sisusb)) { 684 - mutex_unlock(&sisusb->lock); 685 - return; 686 - } 687 - 688 - vc_scrolldelta_helper(c, lines, sisusb->con_rolled_over, 689 - (void *)sisusb->scrbuf, sisusb->scrbuf_size); 690 - 691 - sisusbcon_set_start_address(sisusb, c); 692 - 693 - mutex_unlock(&sisusb->lock); 694 - } 695 - 696 - /* Interface routine */ 697 - static void 698 - sisusbcon_cursor(struct vc_data *c, int mode) 699 - { 700 - struct sisusb_usb_data *sisusb; 701 - int from, to, baseline; 702 - 703 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 704 - if (!sisusb) 705 - return; 706 - 707 - /* sisusb->lock is down */ 708 - 709 - if (sisusb_is_inactive(c, sisusb)) { 710 - mutex_unlock(&sisusb->lock); 711 - return; 712 - } 713 - 714 - if (c->vc_origin != c->vc_visible_origin) { 715 - c->vc_visible_origin = c->vc_origin; 716 - sisusbcon_set_start_address(sisusb, c); 717 - } 718 - 719 - if (mode == CM_ERASE) { 720 - sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20); 721 - sisusb->sisusb_cursor_size_to = -1; 722 - mutex_unlock(&sisusb->lock); 723 - return; 724 - } 725 - 726 - sisusb_set_cursor(sisusb, (c->vc_pos - sisusb->scrbuf) / 2); 727 - 728 - baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2); 729 - 730 - switch (CUR_SIZE(c->vc_cursor_type)) { 731 - case CUR_BLOCK: from = 1; 732 - to = c->vc_font.height; 733 - break; 734 - case CUR_TWO_THIRDS: from = c->vc_font.height / 3; 735 - to = baseline; 736 - break; 737 - case CUR_LOWER_HALF: from = c->vc_font.height / 2; 738 - to = baseline; 739 - break; 740 - case CUR_LOWER_THIRD: from = (c->vc_font.height * 2) / 3; 741 - to = baseline; 742 - break; 743 - case CUR_NONE: from = 31; 744 - to = 30; 745 - break; 746 - default: 747 - case CUR_UNDERLINE: from = baseline - 1; 748 - to = baseline; 749 - break; 750 - } 751 - 752 - if (sisusb->sisusb_cursor_size_from != from || 753 - sisusb->sisusb_cursor_size_to != to) { 754 - 755 - sisusb_setidxreg(sisusb, SISCR, 0x0a, from); 756 - sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0, to); 757 - 758 - sisusb->sisusb_cursor_size_from = from; 759 - sisusb->sisusb_cursor_size_to = to; 760 - } 761 - 762 - mutex_unlock(&sisusb->lock); 763 - } 764 - 765 - static bool 766 - sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, 767 - unsigned int t, unsigned int b, enum con_scroll dir, 768 - unsigned int lines) 769 - { 770 - int cols = sisusb->sisusb_num_columns; 771 - int length = ((b - t) * cols) * 2; 772 - u16 eattr = c->vc_video_erase_char; 773 - 774 - /* sisusb->lock is down */ 775 - 776 - /* Scroll an area which does not match the 777 - * visible screen's dimensions. This needs 778 - * to be done separately, as it does not 779 - * use hardware panning. 780 - */ 781 - 782 - switch (dir) { 783 - 784 - case SM_UP: 785 - memmove(sisusb_vaddr(sisusb, c, 0, t), 786 - sisusb_vaddr(sisusb, c, 0, t + lines), 787 - (b - t - lines) * cols * 2); 788 - sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, b - lines), 789 - eattr, lines * cols * 2); 790 - break; 791 - 792 - case SM_DOWN: 793 - memmove(sisusb_vaddr(sisusb, c, 0, t + lines), 794 - sisusb_vaddr(sisusb, c, 0, t), 795 - (b - t - lines) * cols * 2); 796 - sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, t), eattr, 797 - lines * cols * 2); 798 - break; 799 - } 800 - 801 - sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, 0, t), 802 - sisusb_haddr(sisusb, c, 0, t), length); 803 - 804 - mutex_unlock(&sisusb->lock); 805 - 806 - return true; 807 - } 808 - 809 - /* Interface routine */ 810 - static bool 811 - sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, 812 - enum con_scroll dir, unsigned int lines) 813 - { 814 - struct sisusb_usb_data *sisusb; 815 - u16 eattr = c->vc_video_erase_char; 816 - int copyall = 0; 817 - unsigned long oldorigin; 818 - unsigned int delta = lines * c->vc_size_row; 819 - 820 - /* Returning != 0 means we have done the scrolling successfully. 821 - * Returning 0 makes vt do the scrolling on its own. 822 - * Note that con_scroll is only called if the console is 823 - * visible. In that case, the origin should be our buffer, 824 - * not the vt's private one. 825 - */ 826 - 827 - if (!lines) 828 - return true; 829 - 830 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 831 - if (!sisusb) 832 - return false; 833 - 834 - /* sisusb->lock is down */ 835 - 836 - if (sisusb_is_inactive(c, sisusb)) { 837 - mutex_unlock(&sisusb->lock); 838 - return false; 839 - } 840 - 841 - /* Special case */ 842 - if (t || b != c->vc_rows) 843 - return sisusbcon_scroll_area(c, sisusb, t, b, dir, lines); 844 - 845 - if (c->vc_origin != c->vc_visible_origin) { 846 - c->vc_visible_origin = c->vc_origin; 847 - sisusbcon_set_start_address(sisusb, c); 848 - } 849 - 850 - /* limit amount to maximum realistic size */ 851 - if (lines > c->vc_rows) 852 - lines = c->vc_rows; 853 - 854 - oldorigin = c->vc_origin; 855 - 856 - switch (dir) { 857 - 858 - case SM_UP: 859 - 860 - if (c->vc_scr_end + delta >= 861 - sisusb->scrbuf + sisusb->scrbuf_size) { 862 - memcpy((u16 *)sisusb->scrbuf, 863 - (u16 *)(oldorigin + delta), 864 - c->vc_screenbuf_size - delta); 865 - c->vc_origin = sisusb->scrbuf; 866 - sisusb->con_rolled_over = oldorigin - sisusb->scrbuf; 867 - copyall = 1; 868 - } else 869 - c->vc_origin += delta; 870 - 871 - sisusbcon_memsetw( 872 - (u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), 873 - eattr, delta); 874 - 875 - break; 876 - 877 - case SM_DOWN: 878 - 879 - if (oldorigin - delta < sisusb->scrbuf) { 880 - memmove((void *)sisusb->scrbuf + sisusb->scrbuf_size - 881 - c->vc_screenbuf_size + delta, 882 - (u16 *)oldorigin, 883 - c->vc_screenbuf_size - delta); 884 - c->vc_origin = sisusb->scrbuf + 885 - sisusb->scrbuf_size - 886 - c->vc_screenbuf_size; 887 - sisusb->con_rolled_over = 0; 888 - copyall = 1; 889 - } else 890 - c->vc_origin -= delta; 891 - 892 - c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; 893 - 894 - scr_memsetw((u16 *)(c->vc_origin), eattr, delta); 895 - 896 - break; 897 - } 898 - 899 - if (copyall) 900 - sisusb_copy_memory(sisusb, 901 - (u8 *)c->vc_origin, 902 - sisusb_haddr(sisusb, c, 0, 0), 903 - c->vc_screenbuf_size); 904 - else if (dir == SM_UP) 905 - sisusb_copy_memory(sisusb, 906 - (u8 *)c->vc_origin + c->vc_screenbuf_size - delta, 907 - sisusb_haddr(sisusb, c, 0, 0) + 908 - c->vc_screenbuf_size - delta, 909 - delta); 910 - else 911 - sisusb_copy_memory(sisusb, 912 - (u8 *)c->vc_origin, 913 - sisusb_haddr(sisusb, c, 0, 0), 914 - delta); 915 - 916 - c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; 917 - c->vc_visible_origin = c->vc_origin; 918 - 919 - sisusbcon_set_start_address(sisusb, c); 920 - 921 - c->vc_pos = c->vc_pos - oldorigin + c->vc_origin; 922 - 923 - mutex_unlock(&sisusb->lock); 924 - 925 - return true; 926 - } 927 - 928 - /* Interface routine */ 929 - static int 930 - sisusbcon_set_origin(struct vc_data *c) 931 - { 932 - struct sisusb_usb_data *sisusb; 933 - 934 - /* Returning != 0 means we were successful. 935 - * Returning 0 will vt make to use its own 936 - * screenbuffer as the origin. 937 - */ 938 - 939 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 940 - if (!sisusb) 941 - return 0; 942 - 943 - /* sisusb->lock is down */ 944 - 945 - if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) { 946 - mutex_unlock(&sisusb->lock); 947 - return 0; 948 - } 949 - 950 - c->vc_origin = c->vc_visible_origin = sisusb->scrbuf; 951 - 952 - sisusbcon_set_start_address(sisusb, c); 953 - 954 - sisusb->con_rolled_over = 0; 955 - 956 - mutex_unlock(&sisusb->lock); 957 - 958 - return true; 959 - } 960 - 961 - /* Interface routine */ 962 - static int 963 - sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows, 964 - unsigned int user) 965 - { 966 - struct sisusb_usb_data *sisusb; 967 - int fh; 968 - 969 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 970 - if (!sisusb) 971 - return -ENODEV; 972 - 973 - fh = sisusb->current_font_height; 974 - 975 - mutex_unlock(&sisusb->lock); 976 - 977 - /* We are quite unflexible as regards resizing. The vt code 978 - * handles sizes where the line length isn't equal the pitch 979 - * quite badly. As regards the rows, our panning tricks only 980 - * work well if the number of rows equals the visible number 981 - * of rows. 982 - */ 983 - 984 - if (newcols != 80 || c->vc_scan_lines / fh != newrows) 985 - return -EINVAL; 986 - 987 - return 0; 988 - } 989 - 990 - int 991 - sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, 992 - u8 *arg, int cmapsz, int ch512, int dorecalc, 993 - struct vc_data *c, int fh, int uplock) 994 - { 995 - int font_select = 0x00, i, err = 0; 996 - u32 offset = 0; 997 - u8 dummy; 998 - 999 - /* sisusb->lock is down */ 1000 - 1001 - /* 1002 - * The default font is kept in slot 0. 1003 - * A user font is loaded in slot 2 (256 ch) 1004 - * or 2+3 (512 ch). 1005 - */ 1006 - 1007 - if ((slot != 0 && slot != 2) || !fh) { 1008 - if (uplock) 1009 - mutex_unlock(&sisusb->lock); 1010 - return -EINVAL; 1011 - } 1012 - 1013 - if (set) 1014 - sisusb->font_slot = slot; 1015 - 1016 - /* Default font is always 256 */ 1017 - if (slot == 0) 1018 - ch512 = 0; 1019 - else 1020 - offset = 4 * cmapsz; 1021 - 1022 - font_select = (slot == 0) ? 0x00 : (ch512 ? 0x0e : 0x0a); 1023 - 1024 - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */ 1025 - err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x04); /* Write to plane 2 */ 1026 - err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x07); /* Memory mode a0-bf */ 1027 - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset */ 1028 - 1029 - if (err) 1030 - goto font_op_error; 1031 - 1032 - err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x03); /* Select plane read 2 */ 1033 - err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x00); /* Disable odd/even */ 1034 - err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x00); /* Address range a0-bf */ 1035 - 1036 - if (err) 1037 - goto font_op_error; 1038 - 1039 - if (arg) { 1040 - if (set) 1041 - for (i = 0; i < cmapsz; i++) { 1042 - err |= sisusb_writeb(sisusb, 1043 - sisusb->vrambase + offset + i, 1044 - arg[i]); 1045 - if (err) 1046 - break; 1047 - } 1048 - else 1049 - for (i = 0; i < cmapsz; i++) { 1050 - err |= sisusb_readb(sisusb, 1051 - sisusb->vrambase + offset + i, 1052 - &arg[i]); 1053 - if (err) 1054 - break; 1055 - } 1056 - 1057 - /* 1058 - * In 512-character mode, the character map is not contiguous if 1059 - * we want to remain EGA compatible -- which we do 1060 - */ 1061 - 1062 - if (ch512) { 1063 - if (set) 1064 - for (i = 0; i < cmapsz; i++) { 1065 - err |= sisusb_writeb(sisusb, 1066 - sisusb->vrambase + offset + 1067 - (2 * cmapsz) + i, 1068 - arg[cmapsz + i]); 1069 - if (err) 1070 - break; 1071 - } 1072 - else 1073 - for (i = 0; i < cmapsz; i++) { 1074 - err |= sisusb_readb(sisusb, 1075 - sisusb->vrambase + offset + 1076 - (2 * cmapsz) + i, 1077 - &arg[cmapsz + i]); 1078 - if (err) 1079 - break; 1080 - } 1081 - } 1082 - } 1083 - 1084 - if (err) 1085 - goto font_op_error; 1086 - 1087 - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */ 1088 - err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x03); /* Write to planes 0+1 */ 1089 - err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x03); /* Memory mode a0-bf */ 1090 - if (set) 1091 - sisusb_setidxreg(sisusb, SISSR, 0x03, font_select); 1092 - err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset end */ 1093 - 1094 - if (err) 1095 - goto font_op_error; 1096 - 1097 - err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x00); /* Select plane read 0 */ 1098 - err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x10); /* Enable odd/even */ 1099 - err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x06); /* Address range b8-bf */ 1100 - 1101 - if (err) 1102 - goto font_op_error; 1103 - 1104 - if ((set) && (ch512 != sisusb->current_font_512)) { 1105 - 1106 - /* Font is shared among all our consoles. 1107 - * And so is the hi_font_mask. 1108 - */ 1109 - for (i = 0; i < MAX_NR_CONSOLES; i++) { 1110 - struct vc_data *d = vc_cons[i].d; 1111 - if (d && d->vc_sw == &sisusb_con) 1112 - d->vc_hi_font_mask = ch512 ? 0x0800 : 0; 1113 - } 1114 - 1115 - sisusb->current_font_512 = ch512; 1116 - 1117 - /* color plane enable register: 1118 - 256-char: enable intensity bit 1119 - 512-char: disable intensity bit */ 1120 - sisusb_getreg(sisusb, SISINPSTAT, &dummy); 1121 - sisusb_setreg(sisusb, SISAR, 0x12); 1122 - sisusb_setreg(sisusb, SISAR, ch512 ? 0x07 : 0x0f); 1123 - 1124 - sisusb_getreg(sisusb, SISINPSTAT, &dummy); 1125 - sisusb_setreg(sisusb, SISAR, 0x20); 1126 - sisusb_getreg(sisusb, SISINPSTAT, &dummy); 1127 - } 1128 - 1129 - if (dorecalc) { 1130 - 1131 - /* 1132 - * Adjust the screen to fit a font of a certain height 1133 - */ 1134 - 1135 - unsigned char ovr, vde, fsr; 1136 - int rows = 0, maxscan = 0; 1137 - 1138 - if (c) { 1139 - 1140 - /* Number of video rows */ 1141 - rows = c->vc_scan_lines / fh; 1142 - /* Scan lines to actually display-1 */ 1143 - maxscan = rows * fh - 1; 1144 - 1145 - /*printk(KERN_DEBUG "sisusb recalc rows %d maxscan %d fh %d sl %d\n", 1146 - rows, maxscan, fh, c->vc_scan_lines);*/ 1147 - 1148 - sisusb_getidxreg(sisusb, SISCR, 0x07, &ovr); 1149 - vde = maxscan & 0xff; 1150 - ovr = (ovr & 0xbd) | 1151 - ((maxscan & 0x100) >> 7) | 1152 - ((maxscan & 0x200) >> 3); 1153 - sisusb_setidxreg(sisusb, SISCR, 0x07, ovr); 1154 - sisusb_setidxreg(sisusb, SISCR, 0x12, vde); 1155 - 1156 - } 1157 - 1158 - sisusb_getidxreg(sisusb, SISCR, 0x09, &fsr); 1159 - fsr = (fsr & 0xe0) | (fh - 1); 1160 - sisusb_setidxreg(sisusb, SISCR, 0x09, fsr); 1161 - sisusb->current_font_height = fh; 1162 - 1163 - sisusb->sisusb_cursor_size_from = -1; 1164 - sisusb->sisusb_cursor_size_to = -1; 1165 - 1166 - } 1167 - 1168 - if (uplock) 1169 - mutex_unlock(&sisusb->lock); 1170 - 1171 - if (dorecalc && c) { 1172 - int rows = c->vc_scan_lines / fh; 1173 - 1174 - /* Now adjust our consoles' size */ 1175 - 1176 - for (i = 0; i < MAX_NR_CONSOLES; i++) { 1177 - struct vc_data *vc = vc_cons[i].d; 1178 - 1179 - if (vc && vc->vc_sw == &sisusb_con) { 1180 - if (con_is_visible(vc)) { 1181 - vc->vc_sw->con_cursor(vc, CM_DRAW); 1182 - } 1183 - vc->vc_font.height = fh; 1184 - vc_resize(vc, 0, rows); 1185 - } 1186 - } 1187 - } 1188 - 1189 - return 0; 1190 - 1191 - font_op_error: 1192 - if (uplock) 1193 - mutex_unlock(&sisusb->lock); 1194 - 1195 - return -EIO; 1196 - } 1197 - 1198 - /* Interface routine */ 1199 - static int 1200 - sisusbcon_font_set(struct vc_data *c, struct console_font *font, 1201 - unsigned int flags) 1202 - { 1203 - struct sisusb_usb_data *sisusb; 1204 - unsigned charcount = font->charcount; 1205 - 1206 - if (font->width != 8 || (charcount != 256 && charcount != 512)) 1207 - return -EINVAL; 1208 - 1209 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 1210 - if (!sisusb) 1211 - return -ENODEV; 1212 - 1213 - /* sisusb->lock is down */ 1214 - 1215 - /* Save the user-provided font into a buffer. This 1216 - * is used for restoring text mode after quitting 1217 - * from X and for the con_getfont routine. 1218 - */ 1219 - if (sisusb->font_backup) { 1220 - if (sisusb->font_backup_size < charcount) { 1221 - vfree(sisusb->font_backup); 1222 - sisusb->font_backup = NULL; 1223 - } 1224 - } 1225 - 1226 - if (!sisusb->font_backup) 1227 - sisusb->font_backup = vmalloc(array_size(charcount, 32)); 1228 - 1229 - if (sisusb->font_backup) { 1230 - memcpy(sisusb->font_backup, font->data, array_size(charcount, 32)); 1231 - sisusb->font_backup_size = charcount; 1232 - sisusb->font_backup_height = font->height; 1233 - sisusb->font_backup_512 = (charcount == 512) ? 1 : 0; 1234 - } 1235 - 1236 - /* do_font_op ups sisusb->lock */ 1237 - 1238 - return sisusbcon_do_font_op(sisusb, 1, 2, font->data, 1239 - 8192, (charcount == 512), 1240 - (!(flags & KD_FONT_FLAG_DONT_RECALC)) ? 1 : 0, 1241 - c, font->height, 1); 1242 - } 1243 - 1244 - /* Interface routine */ 1245 - static int 1246 - sisusbcon_font_get(struct vc_data *c, struct console_font *font) 1247 - { 1248 - struct sisusb_usb_data *sisusb; 1249 - 1250 - sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); 1251 - if (!sisusb) 1252 - return -ENODEV; 1253 - 1254 - /* sisusb->lock is down */ 1255 - 1256 - font->width = 8; 1257 - font->height = c->vc_font.height; 1258 - font->charcount = 256; 1259 - 1260 - if (!font->data) { 1261 - mutex_unlock(&sisusb->lock); 1262 - return 0; 1263 - } 1264 - 1265 - if (!sisusb->font_backup) { 1266 - mutex_unlock(&sisusb->lock); 1267 - return -ENODEV; 1268 - } 1269 - 1270 - /* Copy 256 chars only, like vgacon */ 1271 - memcpy(font->data, sisusb->font_backup, 256 * 32); 1272 - 1273 - mutex_unlock(&sisusb->lock); 1274 - 1275 - return 0; 1276 - } 1277 - 1278 - /* 1279 - * The console `switch' structure for the sisusb console 1280 - */ 1281 - 1282 - static const struct consw sisusb_con = { 1283 - .owner = THIS_MODULE, 1284 - .con_startup = sisusbcon_startup, 1285 - .con_init = sisusbcon_init, 1286 - .con_deinit = sisusbcon_deinit, 1287 - .con_clear = sisusbcon_clear, 1288 - .con_putc = sisusbcon_putc, 1289 - .con_putcs = sisusbcon_putcs, 1290 - .con_cursor = sisusbcon_cursor, 1291 - .con_scroll = sisusbcon_scroll, 1292 - .con_switch = sisusbcon_switch, 1293 - .con_blank = sisusbcon_blank, 1294 - .con_font_set = sisusbcon_font_set, 1295 - .con_font_get = sisusbcon_font_get, 1296 - .con_set_palette = sisusbcon_set_palette, 1297 - .con_scrolldelta = sisusbcon_scrolldelta, 1298 - .con_build_attr = sisusbcon_build_attr, 1299 - .con_invert_region = sisusbcon_invert_region, 1300 - .con_set_origin = sisusbcon_set_origin, 1301 - .con_save_screen = sisusbcon_save_screen, 1302 - .con_resize = sisusbcon_resize, 1303 - }; 1304 - 1305 - /* Our very own dummy console driver */ 1306 - 1307 - static const char *sisusbdummycon_startup(void) 1308 - { 1309 - return "SISUSBVGADUMMY"; 1310 - } 1311 - 1312 - static void sisusbdummycon_init(struct vc_data *vc, int init) 1313 - { 1314 - vc->vc_can_do_color = 1; 1315 - if (init) { 1316 - vc->vc_cols = 80; 1317 - vc->vc_rows = 25; 1318 - } else 1319 - vc_resize(vc, 80, 25); 1320 - } 1321 - 1322 - static void sisusbdummycon_deinit(struct vc_data *vc) { } 1323 - static void sisusbdummycon_clear(struct vc_data *vc, int sy, int sx, 1324 - int height, int width) { } 1325 - static void sisusbdummycon_putc(struct vc_data *vc, int c, int ypos, 1326 - int xpos) { } 1327 - static void sisusbdummycon_putcs(struct vc_data *vc, const unsigned short *s, 1328 - int count, int ypos, int xpos) { } 1329 - static void sisusbdummycon_cursor(struct vc_data *vc, int mode) { } 1330 - 1331 - static bool sisusbdummycon_scroll(struct vc_data *vc, unsigned int top, 1332 - unsigned int bottom, enum con_scroll dir, 1333 - unsigned int lines) 1334 - { 1335 - return false; 1336 - } 1337 - 1338 - static int sisusbdummycon_switch(struct vc_data *vc) 1339 - { 1340 - return 0; 1341 - } 1342 - 1343 - static int sisusbdummycon_blank(struct vc_data *vc, int blank, int mode_switch) 1344 - { 1345 - return 0; 1346 - } 1347 - 1348 - static const struct consw sisusb_dummy_con = { 1349 - .owner = THIS_MODULE, 1350 - .con_startup = sisusbdummycon_startup, 1351 - .con_init = sisusbdummycon_init, 1352 - .con_deinit = sisusbdummycon_deinit, 1353 - .con_clear = sisusbdummycon_clear, 1354 - .con_putc = sisusbdummycon_putc, 1355 - .con_putcs = sisusbdummycon_putcs, 1356 - .con_cursor = sisusbdummycon_cursor, 1357 - .con_scroll = sisusbdummycon_scroll, 1358 - .con_switch = sisusbdummycon_switch, 1359 - .con_blank = sisusbdummycon_blank, 1360 - }; 1361 - 1362 - int 1363 - sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) 1364 - { 1365 - int i, ret; 1366 - 1367 - mutex_lock(&sisusb->lock); 1368 - 1369 - /* Erm.. that should not happen */ 1370 - if (sisusb->haveconsole || !sisusb->SiS_Pr) { 1371 - mutex_unlock(&sisusb->lock); 1372 - return 1; 1373 - } 1374 - 1375 - sisusb->con_first = first; 1376 - sisusb->con_last = last; 1377 - 1378 - if (first > last || 1379 - first > MAX_NR_CONSOLES || 1380 - last > MAX_NR_CONSOLES) { 1381 - mutex_unlock(&sisusb->lock); 1382 - return 1; 1383 - } 1384 - 1385 - /* If gfxcore not initialized or no consoles given, quit graciously */ 1386 - if (!sisusb->gfxinit || first < 1 || last < 1) { 1387 - mutex_unlock(&sisusb->lock); 1388 - return 0; 1389 - } 1390 - 1391 - sisusb->sisusb_cursor_loc = -1; 1392 - sisusb->sisusb_cursor_size_from = -1; 1393 - sisusb->sisusb_cursor_size_to = -1; 1394 - 1395 - /* Set up text mode (and upload default font) */ 1396 - if (sisusb_reset_text_mode(sisusb, 1)) { 1397 - mutex_unlock(&sisusb->lock); 1398 - dev_err(&sisusb->sisusb_dev->dev, "Failed to set up text mode\n"); 1399 - return 1; 1400 - } 1401 - 1402 - /* Initialize some gfx registers */ 1403 - sisusb_initialize(sisusb); 1404 - 1405 - for (i = first - 1; i <= last - 1; i++) { 1406 - /* Save sisusb for our interface routines */ 1407 - mysisusbs[i] = sisusb; 1408 - } 1409 - 1410 - /* Initial console setup */ 1411 - sisusb->sisusb_num_columns = 80; 1412 - 1413 - /* Use a 32K buffer (matches b8000-bffff area) */ 1414 - sisusb->scrbuf_size = 32 * 1024; 1415 - 1416 - /* Allocate screen buffer */ 1417 - if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { 1418 - mutex_unlock(&sisusb->lock); 1419 - dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate screen buffer\n"); 1420 - return 1; 1421 - } 1422 - 1423 - mutex_unlock(&sisusb->lock); 1424 - 1425 - /* Now grab the desired console(s) */ 1426 - console_lock(); 1427 - ret = do_take_over_console(&sisusb_con, first - 1, last - 1, 0); 1428 - console_unlock(); 1429 - if (!ret) 1430 - sisusb->haveconsole = 1; 1431 - else { 1432 - for (i = first - 1; i <= last - 1; i++) 1433 - mysisusbs[i] = NULL; 1434 - } 1435 - 1436 - return ret; 1437 - } 1438 - 1439 - void 1440 - sisusb_console_exit(struct sisusb_usb_data *sisusb) 1441 - { 1442 - int i; 1443 - 1444 - /* This is called if the device is disconnected 1445 - * and while disconnect and lock semaphores 1446 - * are up. This should be save because we 1447 - * can't lose our sisusb any other way but by 1448 - * disconnection (and hence, the disconnect 1449 - * sema is for protecting all other access 1450 - * functions from disconnection, not the 1451 - * other way round). 1452 - */ 1453 - 1454 - /* Now what do we do in case of disconnection: 1455 - * One alternative would be to simply call 1456 - * give_up_console(). Nah, not a good idea. 1457 - * give_up_console() is obviously buggy as it 1458 - * only discards the consw pointer from the 1459 - * driver_map, but doesn't adapt vc->vc_sw 1460 - * of the affected consoles. Hence, the next 1461 - * call to any of the console functions will 1462 - * eventually take a trip to oops county. 1463 - * Also, give_up_console for some reason 1464 - * doesn't decrement our module refcount. 1465 - * Instead, we switch our consoles to a private 1466 - * dummy console. This, of course, keeps our 1467 - * refcount up as well, but it works perfectly. 1468 - */ 1469 - 1470 - if (sisusb->haveconsole) { 1471 - for (i = 0; i < MAX_NR_CONSOLES; i++) 1472 - if (sisusb->havethisconsole[i]) { 1473 - console_lock(); 1474 - do_take_over_console(&sisusb_dummy_con, i, i, 0); 1475 - console_unlock(); 1476 - /* At this point, con_deinit for all our 1477 - * consoles is executed by do_take_over_console(). 1478 - */ 1479 - } 1480 - sisusb->haveconsole = 0; 1481 - } 1482 - 1483 - vfree((void *)sisusb->scrbuf); 1484 - sisusb->scrbuf = 0; 1485 - 1486 - vfree(sisusb->font_backup); 1487 - sisusb->font_backup = NULL; 1488 - } 1489 - 1490 - void __init sisusb_init_concode(void) 1491 - { 1492 - int i; 1493 - 1494 - for (i = 0; i < MAX_NR_CONSOLES; i++) 1495 - mysisusbs[i] = NULL; 1496 - }
-955
drivers/usb/misc/sisusbvga/sisusb_init.c
··· 1 - // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 - /* 3 - * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles 4 - * 5 - * Display mode initializing code 6 - * 7 - * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 8 - * 9 - * If distributed as part of the Linux kernel, this code is licensed under the 10 - * terms of the GPL v2. 11 - * 12 - * Otherwise, the following license terms apply: 13 - * 14 - * * Redistribution and use in source and binary forms, with or without 15 - * * modification, are permitted provided that the following conditions 16 - * * are met: 17 - * * 1) Redistributions of source code must retain the above copyright 18 - * * notice, this list of conditions and the following disclaimer. 19 - * * 2) Redistributions in binary form must reproduce the above copyright 20 - * * notice, this list of conditions and the following disclaimer in the 21 - * * documentation and/or other materials provided with the distribution. 22 - * * 3) The name of the author may not be used to endorse or promote products 23 - * * derived from this software without specific prior written permission. 24 - * * 25 - * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26 - * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 - * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 - * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 - * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 - * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 - * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 - * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 - * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 - * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 - * 36 - * Author: Thomas Winischhofer <thomas@winischhofer.net> 37 - * 38 - */ 39 - 40 - #include <linux/module.h> 41 - #include <linux/kernel.h> 42 - #include <linux/errno.h> 43 - #include <linux/poll.h> 44 - #include <linux/spinlock.h> 45 - 46 - #include "sisusb.h" 47 - #include "sisusb_init.h" 48 - #include "sisusb_tables.h" 49 - 50 - /*********************************************/ 51 - /* POINTER INITIALIZATION */ 52 - /*********************************************/ 53 - 54 - static void SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) 55 - { 56 - SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; 57 - SiS_Pr->SiS_StandTable = SiSUSB_StandTable; 58 - 59 - SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; 60 - SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; 61 - SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; 62 - SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; 63 - 64 - SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData; 65 - } 66 - 67 - /*********************************************/ 68 - /* HELPER: SetReg, GetReg */ 69 - /*********************************************/ 70 - 71 - static void 72 - SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, 73 - unsigned short index, unsigned short data) 74 - { 75 - sisusb_setidxreg(SiS_Pr->sisusb, port, index, data); 76 - } 77 - 78 - static void 79 - SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, 80 - unsigned short data) 81 - { 82 - sisusb_setreg(SiS_Pr->sisusb, port, data); 83 - } 84 - 85 - static unsigned char 86 - SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index) 87 - { 88 - u8 data; 89 - 90 - sisusb_getidxreg(SiS_Pr->sisusb, port, index, &data); 91 - 92 - return data; 93 - } 94 - 95 - static unsigned char 96 - SiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port) 97 - { 98 - u8 data; 99 - 100 - sisusb_getreg(SiS_Pr->sisusb, port, &data); 101 - 102 - return data; 103 - } 104 - 105 - static void 106 - SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, 107 - unsigned short index, unsigned short DataAND, 108 - unsigned short DataOR) 109 - { 110 - sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR); 111 - } 112 - 113 - static void 114 - SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, 115 - unsigned short index, unsigned short DataAND) 116 - { 117 - sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND); 118 - } 119 - 120 - static void 121 - SiS_SetRegOR(struct SiS_Private *SiS_Pr, unsigned long port, 122 - unsigned short index, unsigned short DataOR) 123 - { 124 - sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR); 125 - } 126 - 127 - /*********************************************/ 128 - /* HELPER: DisplayOn, DisplayOff */ 129 - /*********************************************/ 130 - 131 - static void SiS_DisplayOn(struct SiS_Private *SiS_Pr) 132 - { 133 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF); 134 - } 135 - 136 - /*********************************************/ 137 - /* HELPER: Init Port Addresses */ 138 - /*********************************************/ 139 - 140 - static void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) 141 - { 142 - SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; 143 - SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; 144 - SiS_Pr->SiS_P3c0 = BaseAddr + 0x10; 145 - SiS_Pr->SiS_P3ce = BaseAddr + 0x1e; 146 - SiS_Pr->SiS_P3c2 = BaseAddr + 0x12; 147 - SiS_Pr->SiS_P3ca = BaseAddr + 0x1a; 148 - SiS_Pr->SiS_P3c6 = BaseAddr + 0x16; 149 - SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; 150 - SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; 151 - SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; 152 - SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; 153 - SiS_Pr->SiS_P3cc = BaseAddr + 0x1c; 154 - SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; 155 - SiS_Pr->SiS_P3da = BaseAddr + 0x2a; 156 - SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; 157 - } 158 - 159 - /*********************************************/ 160 - /* HELPER: GetSysFlags */ 161 - /*********************************************/ 162 - 163 - static void SiS_GetSysFlags(struct SiS_Private *SiS_Pr) 164 - { 165 - SiS_Pr->SiS_MyCR63 = 0x63; 166 - } 167 - 168 - /*********************************************/ 169 - /* HELPER: Init PCI & Engines */ 170 - /*********************************************/ 171 - 172 - static void SiSInitPCIetc(struct SiS_Private *SiS_Pr) 173 - { 174 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); 175 - /* - Enable 2D (0x40) 176 - * - Enable 3D (0x02) 177 - * - Enable 3D vertex command fetch (0x10) 178 - * - Enable 3D command parser (0x08) 179 - * - Enable 3D G/L transformation engine (0x80) 180 - */ 181 - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1E, 0xDA); 182 - } 183 - 184 - /*********************************************/ 185 - /* HELPER: SET SEGMENT REGISTERS */ 186 - /*********************************************/ 187 - 188 - static void SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) 189 - { 190 - unsigned short temp; 191 - 192 - value &= 0x00ff; 193 - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0xf0; 194 - temp |= (value >> 4); 195 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); 196 - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0xf0; 197 - temp |= (value & 0x0f); 198 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); 199 - } 200 - 201 - static void SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) 202 - { 203 - unsigned short temp; 204 - 205 - value &= 0x00ff; 206 - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0x0f; 207 - temp |= (value & 0xf0); 208 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); 209 - temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0x0f; 210 - temp |= (value << 4); 211 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); 212 - } 213 - 214 - static void SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) 215 - { 216 - SiS_SetSegRegLower(SiS_Pr, value); 217 - SiS_SetSegRegUpper(SiS_Pr, value); 218 - } 219 - 220 - static void SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) 221 - { 222 - SiS_SetSegmentReg(SiS_Pr, 0); 223 - } 224 - 225 - static void 226 - SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value) 227 - { 228 - unsigned short temp = value >> 8; 229 - 230 - temp &= 0x07; 231 - temp |= (temp << 4); 232 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1d, temp); 233 - SiS_SetSegmentReg(SiS_Pr, value); 234 - } 235 - 236 - static void SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) 237 - { 238 - SiS_SetSegmentRegOver(SiS_Pr, 0); 239 - } 240 - 241 - static void SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) 242 - { 243 - SiS_ResetSegmentReg(SiS_Pr); 244 - SiS_ResetSegmentRegOver(SiS_Pr); 245 - } 246 - 247 - /*********************************************/ 248 - /* HELPER: SearchModeID */ 249 - /*********************************************/ 250 - 251 - static int 252 - SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, 253 - unsigned short *ModeIdIndex) 254 - { 255 - if ((*ModeNo) <= 0x13) { 256 - 257 - if ((*ModeNo) != 0x03) 258 - return 0; 259 - 260 - (*ModeIdIndex) = 0; 261 - 262 - } else { 263 - 264 - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { 265 - 266 - if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 267 - (*ModeNo)) 268 - break; 269 - 270 - if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 271 - 0xFF) 272 - return 0; 273 - } 274 - 275 - } 276 - 277 - return 1; 278 - } 279 - 280 - /*********************************************/ 281 - /* HELPER: ENABLE CRT1 */ 282 - /*********************************************/ 283 - 284 - static void SiS_HandleCRT1(struct SiS_Private *SiS_Pr) 285 - { 286 - /* Enable CRT1 gating */ 287 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf); 288 - } 289 - 290 - /*********************************************/ 291 - /* HELPER: GetColorDepth */ 292 - /*********************************************/ 293 - 294 - static unsigned short 295 - SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 296 - unsigned short ModeIdIndex) 297 - { 298 - static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; 299 - unsigned short modeflag; 300 - short index; 301 - 302 - if (ModeNo <= 0x13) { 303 - modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 304 - } else { 305 - modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 306 - } 307 - 308 - index = (modeflag & ModeTypeMask) - ModeEGA; 309 - if (index < 0) 310 - index = 0; 311 - return ColorDepth[index]; 312 - } 313 - 314 - /*********************************************/ 315 - /* HELPER: GetOffset */ 316 - /*********************************************/ 317 - 318 - static unsigned short 319 - SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 320 - unsigned short ModeIdIndex, unsigned short rrti) 321 - { 322 - unsigned short xres, temp, colordepth, infoflag; 323 - 324 - infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; 325 - xres = SiS_Pr->SiS_RefIndex[rrti].XRes; 326 - 327 - colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex); 328 - 329 - temp = xres / 16; 330 - 331 - if (infoflag & InterlaceMode) 332 - temp <<= 1; 333 - 334 - temp *= colordepth; 335 - 336 - if (xres % 16) 337 - temp += (colordepth >> 1); 338 - 339 - return temp; 340 - } 341 - 342 - /*********************************************/ 343 - /* SEQ */ 344 - /*********************************************/ 345 - 346 - static void 347 - SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 348 - { 349 - unsigned char SRdata; 350 - int i; 351 - 352 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x00, 0x03); 353 - 354 - SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; 355 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); 356 - 357 - for (i = 2; i <= 4; i++) { 358 - SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1]; 359 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); 360 - } 361 - } 362 - 363 - /*********************************************/ 364 - /* MISC */ 365 - /*********************************************/ 366 - 367 - static void 368 - SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 369 - { 370 - unsigned char Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; 371 - 372 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, Miscdata); 373 - } 374 - 375 - /*********************************************/ 376 - /* CRTC */ 377 - /*********************************************/ 378 - 379 - static void 380 - SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 381 - { 382 - unsigned char CRTCdata; 383 - unsigned short i; 384 - 385 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); 386 - 387 - for (i = 0; i <= 0x18; i++) { 388 - CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; 389 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); 390 - } 391 - } 392 - 393 - /*********************************************/ 394 - /* ATT */ 395 - /*********************************************/ 396 - 397 - static void 398 - SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 399 - { 400 - unsigned char ARdata; 401 - unsigned short i; 402 - 403 - for (i = 0; i <= 0x13; i++) { 404 - ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; 405 - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); 406 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); 407 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, ARdata); 408 - } 409 - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); 410 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x14); 411 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x00); 412 - 413 - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); 414 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x20); 415 - SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); 416 - } 417 - 418 - /*********************************************/ 419 - /* GRC */ 420 - /*********************************************/ 421 - 422 - static void 423 - SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 424 - { 425 - unsigned char GRdata; 426 - unsigned short i; 427 - 428 - for (i = 0; i <= 0x08; i++) { 429 - GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; 430 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata); 431 - } 432 - 433 - if (SiS_Pr->SiS_ModeType > ModeVGA) { 434 - /* 256 color disable */ 435 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3ce, 0x05, 0xBF); 436 - } 437 - } 438 - 439 - /*********************************************/ 440 - /* CLEAR EXTENDED REGISTERS */ 441 - /*********************************************/ 442 - 443 - static void SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 444 - { 445 - int i; 446 - 447 - for (i = 0x0A; i <= 0x0E; i++) { 448 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00); 449 - } 450 - 451 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x37, 0xFE); 452 - } 453 - 454 - /*********************************************/ 455 - /* Get rate index */ 456 - /*********************************************/ 457 - 458 - static unsigned short 459 - SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 460 - unsigned short ModeIdIndex) 461 - { 462 - unsigned short rrti, i, index, temp; 463 - 464 - if (ModeNo <= 0x13) 465 - return 0xFFFF; 466 - 467 - index = SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x33) & 0x0F; 468 - if (index > 0) 469 - index--; 470 - 471 - rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; 472 - ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID; 473 - 474 - i = 0; 475 - do { 476 - if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo) 477 - break; 478 - 479 - temp = 480 - SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask; 481 - if (temp < SiS_Pr->SiS_ModeType) 482 - break; 483 - 484 - i++; 485 - index--; 486 - } while (index != 0xFFFF); 487 - 488 - i--; 489 - 490 - return (rrti + i); 491 - } 492 - 493 - /*********************************************/ 494 - /* SYNC */ 495 - /*********************************************/ 496 - 497 - static void SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) 498 - { 499 - unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8; 500 - sync &= 0xC0; 501 - sync |= 0x2f; 502 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, sync); 503 - } 504 - 505 - /*********************************************/ 506 - /* CRTC/2 */ 507 - /*********************************************/ 508 - 509 - static void 510 - SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 511 - unsigned short ModeIdIndex, unsigned short rrti) 512 - { 513 - unsigned char index; 514 - unsigned short temp, i, j, modeflag; 515 - 516 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); 517 - 518 - modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 519 - 520 - index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC; 521 - 522 - for (i = 0, j = 0; i <= 7; i++, j++) { 523 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, 524 - SiS_Pr->SiS_CRT1Table[index].CR[i]); 525 - } 526 - for (j = 0x10; i <= 10; i++, j++) { 527 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, 528 - SiS_Pr->SiS_CRT1Table[index].CR[i]); 529 - } 530 - for (j = 0x15; i <= 12; i++, j++) { 531 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, 532 - SiS_Pr->SiS_CRT1Table[index].CR[i]); 533 - } 534 - for (j = 0x0A; i <= 15; i++, j++) { 535 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, j, 536 - SiS_Pr->SiS_CRT1Table[index].CR[i]); 537 - } 538 - 539 - temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0; 540 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, temp); 541 - 542 - temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5; 543 - if (modeflag & DoubleScanMode) 544 - temp |= 0x80; 545 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x09, 0x5F, temp); 546 - 547 - if (SiS_Pr->SiS_ModeType > ModeVGA) 548 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x14, 0x4F); 549 - } 550 - 551 - /*********************************************/ 552 - /* OFFSET & PITCH */ 553 - /*********************************************/ 554 - /* (partly overruled by SetPitch() in XF86) */ 555 - /*********************************************/ 556 - 557 - static void 558 - SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 559 - unsigned short ModeIdIndex, unsigned short rrti) 560 - { 561 - unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti); 562 - unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; 563 - unsigned short temp; 564 - 565 - temp = (du >> 8) & 0x0f; 566 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, 0xF0, temp); 567 - 568 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF)); 569 - 570 - if (infoflag & InterlaceMode) 571 - du >>= 1; 572 - 573 - du <<= 5; 574 - temp = (du >> 8) & 0xff; 575 - if (du & 0xff) 576 - temp++; 577 - temp++; 578 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp); 579 - } 580 - 581 - /*********************************************/ 582 - /* VCLK */ 583 - /*********************************************/ 584 - 585 - static void 586 - SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 587 - unsigned short rrti) 588 - { 589 - unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; 590 - unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B; 591 - unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C; 592 - 593 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xCF); 594 - 595 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2B, clka); 596 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2C, clkb); 597 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2D, 0x01); 598 - } 599 - 600 - /*********************************************/ 601 - /* FIFO */ 602 - /*********************************************/ 603 - 604 - static void 605 - SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 606 - unsigned short mi) 607 - { 608 - unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; 609 - 610 - /* disable auto-threshold */ 611 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0xFE); 612 - 613 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0xAE); 614 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x09, 0xF0); 615 - 616 - if (ModeNo <= 0x13) 617 - return; 618 - 619 - if ((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) { 620 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x08, 0x34); 621 - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x3D, 0x01); 622 - } 623 - } 624 - 625 - /*********************************************/ 626 - /* MODE REGISTERS */ 627 - /*********************************************/ 628 - 629 - static void 630 - SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 631 - unsigned short rrti) 632 - { 633 - unsigned short data = 0, VCLK = 0, index = 0; 634 - 635 - if (ModeNo > 0x13) { 636 - index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; 637 - VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 638 - } 639 - 640 - if (VCLK >= 166) 641 - data |= 0x0c; 642 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data); 643 - 644 - if (VCLK >= 166) 645 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1f, 0xe7); 646 - 647 - /* DAC speed */ 648 - data = 0x03; 649 - if (VCLK >= 260) 650 - data = 0x00; 651 - else if (VCLK >= 160) 652 - data = 0x01; 653 - else if (VCLK >= 135) 654 - data = 0x02; 655 - 656 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x07, 0xF8, data); 657 - } 658 - 659 - static void 660 - SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 661 - unsigned short ModeIdIndex, unsigned short rrti) 662 - { 663 - unsigned short data, infoflag = 0, modeflag; 664 - 665 - if (ModeNo <= 0x13) 666 - modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 667 - else { 668 - modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 669 - infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; 670 - } 671 - 672 - /* Disable DPMS */ 673 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1F, 0x3F); 674 - 675 - data = 0; 676 - if (ModeNo > 0x13) { 677 - if (SiS_Pr->SiS_ModeType > ModeEGA) { 678 - data |= 0x02; 679 - data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); 680 - } 681 - if (infoflag & InterlaceMode) 682 - data |= 0x20; 683 - } 684 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x06, 0xC0, data); 685 - 686 - data = 0; 687 - if (infoflag & InterlaceMode) { 688 - /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ 689 - unsigned short hrs = 690 - (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) | 691 - ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2)) 692 - - 3; 693 - unsigned short hto = 694 - (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) | 695 - ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8)) 696 - + 5; 697 - data = hrs - (hto >> 1) + 3; 698 - } 699 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF)); 700 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x1a, 0xFC, (data >> 8)); 701 - 702 - if (modeflag & HalfDCLK) 703 - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0x08); 704 - 705 - data = 0; 706 - if (modeflag & LineCompareOff) 707 - data = 0x08; 708 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0xB7, data); 709 - 710 - if ((SiS_Pr->SiS_ModeType == ModeEGA) && (ModeNo > 0x13)) 711 - SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0F, 0x40); 712 - 713 - SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xfb); 714 - 715 - data = 0x60; 716 - if (SiS_Pr->SiS_ModeType != ModeText) { 717 - data ^= 0x60; 718 - if (SiS_Pr->SiS_ModeType != ModeEGA) 719 - data ^= 0xA0; 720 - } 721 - SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x21, 0x1F, data); 722 - 723 - SiS_SetVCLKState(SiS_Pr, ModeNo, rrti); 724 - 725 - if (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x31) & 0x40) 726 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x2c); 727 - else 728 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x52, 0x6c); 729 - } 730 - 731 - /*********************************************/ 732 - /* LOAD DAC */ 733 - /*********************************************/ 734 - 735 - static void 736 - SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, 737 - unsigned short shiftflag, unsigned short dl, unsigned short ah, 738 - unsigned short al, unsigned short dh) 739 - { 740 - unsigned short d1, d2, d3; 741 - 742 - switch (dl) { 743 - case 0: 744 - d1 = dh; 745 - d2 = ah; 746 - d3 = al; 747 - break; 748 - case 1: 749 - d1 = ah; 750 - d2 = al; 751 - d3 = dh; 752 - break; 753 - default: 754 - d1 = al; 755 - d2 = dh; 756 - d3 = ah; 757 - } 758 - SiS_SetRegByte(SiS_Pr, DACData, (d1 << shiftflag)); 759 - SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag)); 760 - SiS_SetRegByte(SiS_Pr, DACData, (d3 << shiftflag)); 761 - } 762 - 763 - static void 764 - SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 765 - unsigned short mi) 766 - { 767 - unsigned short data, data2, time, i, j, k, m, n, o; 768 - unsigned short si, di, bx, sf; 769 - unsigned long DACAddr, DACData; 770 - const unsigned char *table = NULL; 771 - 772 - if (ModeNo < 0x13) 773 - data = SiS_Pr->SiS_SModeIDTable[mi].St_ModeFlag; 774 - else 775 - data = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; 776 - 777 - data &= DACInfoFlag; 778 - 779 - j = time = 64; 780 - if (data == 0x00) 781 - table = SiS_MDA_DAC; 782 - else if (data == 0x08) 783 - table = SiS_CGA_DAC; 784 - else if (data == 0x10) 785 - table = SiS_EGA_DAC; 786 - else { 787 - j = 16; 788 - time = 256; 789 - table = SiS_VGA_DAC; 790 - } 791 - 792 - DACAddr = SiS_Pr->SiS_P3c8; 793 - DACData = SiS_Pr->SiS_P3c9; 794 - sf = 0; 795 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF); 796 - 797 - SiS_SetRegByte(SiS_Pr, DACAddr, 0x00); 798 - 799 - for (i = 0; i < j; i++) { 800 - data = table[i]; 801 - for (k = 0; k < 3; k++) { 802 - data2 = 0; 803 - if (data & 0x01) 804 - data2 += 0x2A; 805 - if (data & 0x02) 806 - data2 += 0x15; 807 - SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf)); 808 - data >>= 2; 809 - } 810 - } 811 - 812 - if (time == 256) { 813 - for (i = 16; i < 32; i++) { 814 - data = table[i] << sf; 815 - for (k = 0; k < 3; k++) 816 - SiS_SetRegByte(SiS_Pr, DACData, data); 817 - } 818 - si = 32; 819 - for (m = 0; m < 9; m++) { 820 - di = si; 821 - bx = si + 4; 822 - for (n = 0; n < 3; n++) { 823 - for (o = 0; o < 5; o++) { 824 - SiS_WriteDAC(SiS_Pr, DACData, sf, n, 825 - table[di], table[bx], 826 - table[si]); 827 - si++; 828 - } 829 - si -= 2; 830 - for (o = 0; o < 3; o++) { 831 - SiS_WriteDAC(SiS_Pr, DACData, sf, n, 832 - table[di], table[si], 833 - table[bx]); 834 - si--; 835 - } 836 - } 837 - si += 5; 838 - } 839 - } 840 - } 841 - 842 - /*********************************************/ 843 - /* SET CRT1 REGISTER GROUP */ 844 - /*********************************************/ 845 - 846 - static void 847 - SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 848 - unsigned short ModeIdIndex) 849 - { 850 - unsigned short StandTableIndex, rrti; 851 - 852 - SiS_Pr->SiS_CRT1Mode = ModeNo; 853 - 854 - if (ModeNo <= 0x13) 855 - StandTableIndex = 0; 856 - else 857 - StandTableIndex = 1; 858 - 859 - SiS_ResetSegmentRegisters(SiS_Pr); 860 - SiS_SetSeqRegs(SiS_Pr, StandTableIndex); 861 - SiS_SetMiscRegs(SiS_Pr, StandTableIndex); 862 - SiS_SetCRTCRegs(SiS_Pr, StandTableIndex); 863 - SiS_SetATTRegs(SiS_Pr, StandTableIndex); 864 - SiS_SetGRCRegs(SiS_Pr, StandTableIndex); 865 - SiS_ClearExt1Regs(SiS_Pr, ModeNo); 866 - 867 - rrti = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex); 868 - 869 - if (rrti != 0xFFFF) { 870 - SiS_SetCRT1Sync(SiS_Pr, rrti); 871 - SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, rrti); 872 - SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, rrti); 873 - SiS_SetCRT1VCLK(SiS_Pr, ModeNo, rrti); 874 - } 875 - 876 - SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex); 877 - 878 - SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, rrti); 879 - 880 - SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); 881 - 882 - SiS_DisplayOn(SiS_Pr); 883 - } 884 - 885 - /*********************************************/ 886 - /* SiSSetMode() */ 887 - /*********************************************/ 888 - 889 - int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 890 - { 891 - unsigned short ModeIdIndex; 892 - unsigned long BaseAddr = SiS_Pr->IOAddress; 893 - 894 - SiSUSB_InitPtr(SiS_Pr); 895 - SiSUSBRegInit(SiS_Pr, BaseAddr); 896 - SiS_GetSysFlags(SiS_Pr); 897 - 898 - if (!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) 899 - return 0; 900 - 901 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x05, 0x86); 902 - 903 - SiSInitPCIetc(SiS_Pr); 904 - 905 - ModeNo &= 0x7f; 906 - 907 - SiS_Pr->SiS_ModeType = 908 - SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask; 909 - 910 - SiS_Pr->SiS_SetFlag = LowModeTests; 911 - 912 - /* Set mode on CRT1 */ 913 - SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex); 914 - 915 - SiS_HandleCRT1(SiS_Pr); 916 - 917 - SiS_DisplayOn(SiS_Pr); 918 - SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c6, 0xFF); 919 - 920 - /* Store mode number */ 921 - SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x34, ModeNo); 922 - 923 - return 1; 924 - } 925 - 926 - int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) 927 - { 928 - unsigned short ModeNo = 0; 929 - int i; 930 - 931 - SiSUSB_InitPtr(SiS_Pr); 932 - 933 - if (VModeNo == 0x03) { 934 - 935 - ModeNo = 0x03; 936 - 937 - } else { 938 - 939 - i = 0; 940 - do { 941 - 942 - if (SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID == VModeNo) { 943 - ModeNo = SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID; 944 - break; 945 - } 946 - 947 - } while (SiS_Pr->SiS_EModeIDTable[i++].Ext_ModeID != 0xff); 948 - 949 - } 950 - 951 - if (!ModeNo) 952 - return 0; 953 - 954 - return SiSUSBSetMode(SiS_Pr, ModeNo); 955 - }
-180
drivers/usb/misc/sisusbvga/sisusb_init.h
··· 1 - /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 - /* $XFree86$ */ 3 - /* $XdotOrg$ */ 4 - /* 5 - * Data and prototypes for init.c 6 - * 7 - * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 8 - * 9 - * If distributed as part of the Linux kernel, the following license terms 10 - * apply: 11 - * 12 - * * This program is free software; you can redistribute it and/or modify 13 - * * it under the terms of the GNU General Public License as published by 14 - * * the Free Software Foundation; either version 2 of the named License, 15 - * * or any later version. 16 - * * 17 - * * This program is distributed in the hope that it will be useful, 18 - * * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 - * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 - * * GNU General Public License for more details. 21 - * * 22 - * * You should have received a copy of the GNU General Public License 23 - * * along with this program; if not, write to the Free Software 24 - * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 25 - * 26 - * Otherwise, the following license terms apply: 27 - * 28 - * * Redistribution and use in source and binary forms, with or without 29 - * * modification, are permitted provided that the following conditions 30 - * * are met: 31 - * * 1) Redistributions of source code must retain the above copyright 32 - * * notice, this list of conditions and the following disclaimer. 33 - * * 2) Redistributions in binary form must reproduce the above copyright 34 - * * notice, this list of conditions and the following disclaimer in the 35 - * * documentation and/or other materials provided with the distribution. 36 - * * 3) The name of the author may not be used to endorse or promote products 37 - * * derived from this software without specific prior written permission. 38 - * * 39 - * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 40 - * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 41 - * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 42 - * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 43 - * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44 - * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 45 - * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 46 - * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 - * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 48 - * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 - * 50 - * Author: Thomas Winischhofer <thomas@winischhofer.net> 51 - * 52 - */ 53 - 54 - #ifndef _SISUSB_INIT_H_ 55 - #define _SISUSB_INIT_H_ 56 - 57 - /* SiS_ModeType */ 58 - #define ModeText 0x00 59 - #define ModeCGA 0x01 60 - #define ModeEGA 0x02 61 - #define ModeVGA 0x03 62 - #define Mode15Bpp 0x04 63 - #define Mode16Bpp 0x05 64 - #define Mode24Bpp 0x06 65 - #define Mode32Bpp 0x07 66 - 67 - #define ModeTypeMask 0x07 68 - #define IsTextMode 0x07 69 - 70 - #define DACInfoFlag 0x0018 71 - #define MemoryInfoFlag 0x01E0 72 - #define MemorySizeShift 5 73 - 74 - /* modeflag */ 75 - #define Charx8Dot 0x0200 76 - #define LineCompareOff 0x0400 77 - #define CRT2Mode 0x0800 78 - #define HalfDCLK 0x1000 79 - #define NoSupportSimuTV 0x2000 80 - #define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */ 81 - #define DoubleScanMode 0x8000 82 - 83 - /* Infoflag */ 84 - #define SupportTV 0x0008 85 - #define SupportTV1024 0x0800 86 - #define SupportCHTV 0x0800 87 - #define Support64048060Hz 0x0800 /* Special for 640x480 LCD */ 88 - #define SupportHiVision 0x0010 89 - #define SupportYPbPr750p 0x1000 90 - #define SupportLCD 0x0020 91 - #define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */ 92 - #define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */ 93 - #define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */ 94 - #define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */ 95 - #define InterlaceMode 0x0080 96 - #define SyncPP 0x0000 97 - #define SyncPN 0x4000 98 - #define SyncNP 0x8000 99 - #define SyncNN 0xc000 100 - 101 - /* SetFlag */ 102 - #define ProgrammingCRT2 0x0001 103 - #define LowModeTests 0x0002 104 - #define LCDVESATiming 0x0008 105 - #define EnableLVDSDDA 0x0010 106 - #define SetDispDevSwitchFlag 0x0020 107 - #define CheckWinDos 0x0040 108 - #define SetDOSMode 0x0080 109 - 110 - /* Index in ModeResInfo table */ 111 - #define SIS_RI_320x200 0 112 - #define SIS_RI_320x240 1 113 - #define SIS_RI_320x400 2 114 - #define SIS_RI_400x300 3 115 - #define SIS_RI_512x384 4 116 - #define SIS_RI_640x400 5 117 - #define SIS_RI_640x480 6 118 - #define SIS_RI_800x600 7 119 - #define SIS_RI_1024x768 8 120 - #define SIS_RI_1280x1024 9 121 - #define SIS_RI_1600x1200 10 122 - #define SIS_RI_1920x1440 11 123 - #define SIS_RI_2048x1536 12 124 - #define SIS_RI_720x480 13 125 - #define SIS_RI_720x576 14 126 - #define SIS_RI_1280x960 15 127 - #define SIS_RI_800x480 16 128 - #define SIS_RI_1024x576 17 129 - #define SIS_RI_1280x720 18 130 - #define SIS_RI_856x480 19 131 - #define SIS_RI_1280x768 20 132 - #define SIS_RI_1400x1050 21 133 - #define SIS_RI_1152x864 22 /* Up to here SiS conforming */ 134 - #define SIS_RI_848x480 23 135 - #define SIS_RI_1360x768 24 136 - #define SIS_RI_1024x600 25 137 - #define SIS_RI_1152x768 26 138 - #define SIS_RI_768x576 27 139 - #define SIS_RI_1360x1024 28 140 - #define SIS_RI_1680x1050 29 141 - #define SIS_RI_1280x800 30 142 - #define SIS_RI_1920x1080 31 143 - #define SIS_RI_960x540 32 144 - #define SIS_RI_960x600 33 145 - 146 - #define SIS_VIDEO_CAPTURE 0x00 - 0x30 147 - #define SIS_VIDEO_PLAYBACK 0x02 - 0x30 148 - #define SIS_CRT2_PORT_04 0x04 - 0x30 149 - 150 - int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); 151 - int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); 152 - 153 - extern int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data); 154 - extern int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 * data); 155 - extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, 156 - u8 index, u8 data); 157 - extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, 158 - u8 index, u8 * data); 159 - extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, 160 - u8 idx, u8 myand, u8 myor); 161 - extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, 162 - u8 index, u8 myor); 163 - extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, 164 - u8 idx, u8 myand); 165 - 166 - void sisusb_delete(struct kref *kref); 167 - int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); 168 - int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 * data); 169 - int sisusb_copy_memory(struct sisusb_usb_data *sisusb, u8 *src, 170 - u32 dest, int length); 171 - int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); 172 - int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, 173 - u8 * arg, int cmapsz, int ch512, int dorecalc, 174 - struct vc_data *c, int fh, int uplock); 175 - void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); 176 - int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); 177 - void sisusb_console_exit(struct sisusb_usb_data *sisusb); 178 - void sisusb_init_concode(void); 179 - 180 - #endif