⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 viafbdev.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			return 0;	/* Because static u32 pseudo_pal[17]; */		for (i = 0; i < len; i++)			((u32 *) info->pseudo_palette)[i] =			    (*(pred + i) & 0xF800) |			    ((*(pgreen + i) & 0xFC00) >> 5) |			    ((*(pblue + i) & 0xF800) >> 11);		break;	case 32:		if (len > 17)			return 0;		if (ptransp) {			for (i = 0; i < len; i++)				((u32 *) info->pseudo_palette)[i] =				    ((*(ptransp + i) & 0xFF00) << 16) |				    ((*(pred + i) & 0xFF00) << 8) |				    ((*(pgreen + i) & 0xFF00)) |				    ((*(pblue + i) & 0xFF00) >> 8);		} else {			for (i = 0; i < len; i++)				((u32 *) info->pseudo_palette)[i] =				    0x00000000 |				    ((*(pred + i) & 0xFF00) << 8) |				    ((*(pgreen + i) & 0xFF00)) |				    ((*(pblue + i) & 0xFF00) >> 8);		}		break;	}	return 0;}static int viafb_pan_display(struct fb_var_screeninfo *var,	struct fb_info *info){	unsigned int offset;	DEBUG_MSG(KERN_INFO "viafb_pan_display!\n");	offset = (var->xoffset + (var->yoffset * var->xres_virtual)) *	    var->bits_per_pixel / 16;	DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset);	viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3);	viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff);	viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff);	viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff);	return 0;}static int viafb_blank(int blank_mode, struct fb_info *info){	DEBUG_MSG(KERN_INFO "viafb_blank!\n");	/* clear DPMS setting */	switch (blank_mode) {	case FB_BLANK_UNBLANK:		/* Screen: On, HSync: On, VSync: On */		/* control CRT monitor power management */		viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);		break;	case FB_BLANK_HSYNC_SUSPEND:		/* Screen: Off, HSync: Off, VSync: On */		/* control CRT monitor power management */		viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5);		break;	case FB_BLANK_VSYNC_SUSPEND:		/* Screen: Off, HSync: On, VSync: Off */		/* control CRT monitor power management */		viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5);		break;	case FB_BLANK_POWERDOWN:		/* Screen: Off, HSync: Off, VSync: Off */		/* control CRT monitor power management */		viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5);		break;	}	return 0;}static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg){	union {		struct viafb_ioctl_mode viamode;		struct viafb_ioctl_samm viasamm;		struct viafb_driver_version driver_version;		struct fb_var_screeninfo sec_var;		struct _panel_size_pos_info panel_pos_size_para;		struct viafb_ioctl_setting viafb_setting;		struct device_t active_dev;	} u;	u32 state_info = 0;	u32 *viafb_gamma_table;	char driver_name[] = "viafb";	u32 __user *argp = (u32 __user *) arg;	u32 gpu32;	u32 video_dev_info = 0;	DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);	memset(&u, 0, sizeof(u));	switch (cmd) {	case VIAFB_GET_CHIP_INFO:		if (copy_to_user(argp, viaparinfo->chip_info,				sizeof(struct chip_information)))			return -EFAULT;		break;	case VIAFB_GET_INFO_SIZE:		return put_user((u32)sizeof(struct viafb_ioctl_info), argp);	case VIAFB_GET_INFO:		return viafb_ioctl_get_viafb_info(arg);	case VIAFB_HOTPLUG:		return put_user(viafb_ioctl_hotplug(info->var.xres,					      info->var.yres,					      info->var.bits_per_pixel), argp);	case VIAFB_SET_HOTPLUG_FLAG:		if (copy_from_user(&gpu32, argp, sizeof(gpu32)))			return -EFAULT;		viafb_hotplug = (gpu32) ? 1 : 0;		break;	case VIAFB_GET_RESOLUTION:		u.viamode.xres = (u32) viafb_hotplug_Xres;		u.viamode.yres = (u32) viafb_hotplug_Yres;		u.viamode.refresh = (u32) viafb_hotplug_refresh;		u.viamode.bpp = (u32) viafb_hotplug_bpp;		if (viafb_SAMM_ON == 1) {			u.viamode.xres_sec = viafb_second_xres;			u.viamode.yres_sec = viafb_second_yres;			u.viamode.virtual_xres_sec = viafb_second_virtual_xres;			u.viamode.virtual_yres_sec = viafb_second_virtual_yres;			u.viamode.refresh_sec = viafb_refresh1;			u.viamode.bpp_sec = viafb_bpp1;		} else {			u.viamode.xres_sec = 0;			u.viamode.yres_sec = 0;			u.viamode.virtual_xres_sec = 0;			u.viamode.virtual_yres_sec = 0;			u.viamode.refresh_sec = 0;			u.viamode.bpp_sec = 0;		}		if (copy_to_user(argp, &u.viamode, sizeof(u.viamode)))			return -EFAULT;		break;	case VIAFB_GET_SAMM_INFO:		u.viasamm.samm_status = viafb_SAMM_ON;		if (viafb_SAMM_ON == 1) {			if (viafb_dual_fb) {				u.viasamm.size_prim = viaparinfo->fbmem_free;				u.viasamm.size_sec = viaparinfo1->fbmem_free;			} else {				if (viafb_second_size) {					u.viasamm.size_prim =					    viaparinfo->fbmem_free -					    viafb_second_size * 1024 * 1024;					u.viasamm.size_sec =					    viafb_second_size * 1024 * 1024;				} else {					u.viasamm.size_prim =					    viaparinfo->fbmem_free >> 1;					u.viasamm.size_sec =					    (viaparinfo->fbmem_free >> 1);				}			}			u.viasamm.mem_base = viaparinfo->fbmem;			u.viasamm.offset_sec = viafb_second_offset;		} else {			u.viasamm.size_prim =			    viaparinfo->memsize - viaparinfo->fbmem_used;			u.viasamm.size_sec = 0;			u.viasamm.mem_base = viaparinfo->fbmem;			u.viasamm.offset_sec = 0;		}		if (copy_to_user(argp, &u.viasamm, sizeof(u.viasamm)))			return -EFAULT;		break;	case VIAFB_TURN_ON_OUTPUT_DEVICE:		if (copy_from_user(&gpu32, argp, sizeof(gpu32)))			return -EFAULT;		if (gpu32 & CRT_Device)			viafb_crt_enable();		if (gpu32 & DVI_Device)			viafb_dvi_enable();		if (gpu32 & LCD_Device)			viafb_lcd_enable();		break;	case VIAFB_TURN_OFF_OUTPUT_DEVICE:		if (copy_from_user(&gpu32, argp, sizeof(gpu32)))			return -EFAULT;		if (gpu32 & CRT_Device)			viafb_crt_disable();		if (gpu32 & DVI_Device)			viafb_dvi_disable();		if (gpu32 & LCD_Device)			viafb_lcd_disable();		break;	case VIAFB_SET_DEVICE:		if (copy_from_user(&u.active_dev, (void *)argp,			sizeof(u.active_dev)))			return -EFAULT;		viafb_set_device(u.active_dev);		viafb_set_par(info);		break;	case VIAFB_GET_DEVICE:		u.active_dev.crt = viafb_CRT_ON;		u.active_dev.dvi = viafb_DVI_ON;		u.active_dev.lcd = viafb_LCD_ON;		u.active_dev.samm = viafb_SAMM_ON;		u.active_dev.primary_dev = viafb_primary_dev;		u.active_dev.lcd_dsp_cent = viafb_lcd_dsp_method;		u.active_dev.lcd_panel_id = viafb_lcd_panel_id;		u.active_dev.lcd_mode = viafb_lcd_mode;		u.active_dev.xres = viafb_hotplug_Xres;		u.active_dev.yres = viafb_hotplug_Yres;		u.active_dev.xres1 = viafb_second_xres;		u.active_dev.yres1 = viafb_second_yres;		u.active_dev.bpp = viafb_bpp;		u.active_dev.bpp1 = viafb_bpp1;		u.active_dev.refresh = viafb_refresh;		u.active_dev.refresh1 = viafb_refresh1;		u.active_dev.epia_dvi = viafb_platform_epia_dvi;		u.active_dev.lcd_dual_edge = viafb_device_lcd_dualedge;		u.active_dev.bus_width = viafb_bus_width;		if (copy_to_user(argp, &u.active_dev, sizeof(u.active_dev)))			return -EFAULT;		break;	case VIAFB_GET_DRIVER_VERSION:		u.driver_version.iMajorNum = VERSION_MAJOR;		u.driver_version.iKernelNum = VERSION_KERNEL;		u.driver_version.iOSNum = VERSION_OS;		u.driver_version.iMinorNum = VERSION_MINOR;		if (copy_to_user(argp, &u.driver_version,			sizeof(u.driver_version)))			return -EFAULT;		break;	case VIAFB_SET_DEVICE_INFO:		if (copy_from_user(&u.viafb_setting,			argp, sizeof(u.viafb_setting)))			return -EFAULT;		if (apply_device_setting(u.viafb_setting, info) < 0)			return -EINVAL;		break;	case VIAFB_SET_SECOND_MODE:		if (copy_from_user(&u.sec_var, argp, sizeof(u.sec_var)))			return -EFAULT;		apply_second_mode_setting(&u.sec_var);		break;	case VIAFB_GET_DEVICE_INFO:		retrieve_device_setting(&u.viafb_setting);		if (copy_to_user(argp, &u.viafb_setting,				 sizeof(u.viafb_setting)))			return -EFAULT;		break;	case VIAFB_GET_DEVICE_SUPPORT:		viafb_get_device_support_state(&state_info);		if (put_user(state_info, argp))			return -EFAULT;		break;	case VIAFB_GET_DEVICE_CONNECT:		viafb_get_device_connect_state(&state_info);		if (put_user(state_info, argp))			return -EFAULT;		break;	case VIAFB_GET_PANEL_SUPPORT_EXPAND:		state_info =		    viafb_lcd_get_support_expand_state(info->var.xres,						 info->var.yres);		if (put_user(state_info, argp))			return -EFAULT;		break;	case VIAFB_GET_DRIVER_NAME:		if (copy_to_user(argp, driver_name, sizeof(driver_name)))			return -EFAULT;		break;	case VIAFB_SET_GAMMA_LUT:		viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);		if (!viafb_gamma_table)			return -ENOMEM;		if (copy_from_user(viafb_gamma_table, argp,				sizeof(viafb_gamma_table))) {			kfree(viafb_gamma_table);			return -EFAULT;		}		viafb_set_gamma_table(viafb_bpp, viafb_gamma_table);		kfree(viafb_gamma_table);		break;	case VIAFB_GET_GAMMA_LUT:		viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);		if (!viafb_gamma_table)			return -ENOMEM;		viafb_get_gamma_table(viafb_gamma_table);		if (copy_to_user(argp, viafb_gamma_table,			sizeof(viafb_gamma_table))) {			kfree(viafb_gamma_table);			return -EFAULT;		}		kfree(viafb_gamma_table);		break;	case VIAFB_GET_GAMMA_SUPPORT_STATE:		viafb_get_gamma_support_state(viafb_bpp, &state_info);		if (put_user(state_info, argp))			return -EFAULT;		break;	case VIAFB_SET_VIDEO_DEVICE:		get_user(video_dev_info, argp);		viafb_set_video_device(video_dev_info);		break;	case VIAFB_GET_VIDEO_DEVICE:		viafb_get_video_device(&video_dev_info);		if (put_user(video_dev_info, argp))			return -EFAULT;		break;	case VIAFB_SYNC_SURFACE:		DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n");		break;	case VIAFB_GET_DRIVER_CAPS:		break;	case VIAFB_GET_PANEL_MAX_SIZE:		if (copy_from_user(&u.panel_pos_size_para, argp,				   sizeof(u.panel_pos_size_para)))			return -EFAULT;		u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;		if (copy_to_user(argp, &u.panel_pos_size_para,		     sizeof(u.panel_pos_size_para)))			return -EFAULT;		break;	case VIAFB_GET_PANEL_MAX_POSITION:		if (copy_from_user(&u.panel_pos_size_para, argp,				   sizeof(u.panel_pos_size_para)))			return -EFAULT;		u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;		if (copy_to_user(argp, &u.panel_pos_size_para,				 sizeof(u.panel_pos_size_para)))			return -EFAULT;		break;	case VIAFB_GET_PANEL_POSITION:		if (copy_from_user(&u.panel_pos_size_para, argp,				   sizeof(u.panel_pos_size_para)))			return -EFAULT;		u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;		if (copy_to_user(argp, &u.panel_pos_size_para,				 sizeof(u.panel_pos_size_para)))			return -EFAULT;		break;	case VIAFB_GET_PANEL_SIZE:		if (copy_from_user(&u.panel_pos_size_para, argp,				   sizeof(u.panel_pos_size_para)))			return -EFAULT;		u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0;		if (copy_to_user(argp, &u.panel_pos_size_para,				 sizeof(u.panel_pos_size_para)))			return -EFAULT;		break;	case VIAFB_SET_PANEL_POSITION:		if (copy_from_user(&u.panel_pos_size_para, argp,				   sizeof(u.panel_pos_size_para)))			return -EFAULT;		break;	case VIAFB_SET_PANEL_SIZE:		if (copy_from_user(&u.panel_pos_size_para, argp,				   sizeof(u.panel_pos_size_para)))			return -EFAULT;		break;	default:		return -EINVAL;	}	return 0;}static void viafb_fillrect(struct fb_info *info,	const struct fb_fillrect *rect){	u32 col = 0, rop = 0;	int pitch;	if (!viafb_accel) {		cfb_fillrect(info, rect);		return;	}	if (!rect->width || !rect->height)		return;	switch (rect->rop) {	case ROP_XOR:		rop = 0x5A;		break;	case ROP_COPY:	default:		rop = 0xF0;		break;	}	switch (info->var.bits_per_pixel) {	case 8:		col = rect->color;		break;	case 16:		col = ((u32 *) (info->pseudo_palette))[rect->color];		break;	case 32:		col = ((u32 *) (info->pseudo_palette))[rect->color];		break;	}	/* BitBlt Source Address */	writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);	/* Source Base Address */	writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);	/* Destination Base Address */	writel(((unsigned long) (info->screen_base) -		   (unsigned long) viafb_FB_MM) >> 3,		   viaparinfo->io_virt + VIA_REG_DSTBASE);	/* Pitch */	pitch = (info->var.xres_virtual + 7) & ~7;	writel(VIA_PITCH_ENABLE |		   (((pitch *		      info->var.bits_per_pixel >> 3) >> 3) |		      (((pitch * info->		      var.bits_per_pixel >> 3) >> 3) << 16)),		      viaparinfo->io_virt + VIA_REG_PITCH);	/* BitBlt Destination Address */	writel(((rect->dy << 16) | rect->dx),		viaparinfo->io_virt + VIA_REG_DSTPOS);	/* Dimension: width & height */	writel((((rect->height - 1) << 16) | (rect->width - 1)),		viaparinfo->io_virt + VIA_REG_DIMENSION);	/* Forground color or Destination color */	writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR);	/* GE Command */	writel((0x01 | 0x2000 | (rop << 24)),		viaparinfo->io_virt + VIA_REG_GECMD);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -