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

📄 video.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *  video.c - ACPI Video Driver ($Revision:$) * *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com> *  Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> *  Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or (at *  your option) any later version. * *  This program is distributed in the hope that it will be useful, but *  WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  General Public License for more details. * *  You should have received a copy of the GNU General Public License along *  with this program; if not, write to the Free Software Foundation, Inc., *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/list.h>#include <linux/mutex.h>#include <linux/proc_fs.h>#include <linux/seq_file.h>#include <linux/input.h>#include <linux/backlight.h>#include <linux/video_output.h>#include <asm/uaccess.h>#include <acpi/acpi_bus.h>#include <acpi/acpi_drivers.h>#define ACPI_VIDEO_COMPONENT		0x08000000#define ACPI_VIDEO_CLASS		"video"#define ACPI_VIDEO_BUS_NAME		"Video Bus"#define ACPI_VIDEO_DEVICE_NAME		"Video Device"#define ACPI_VIDEO_NOTIFY_SWITCH	0x80#define ACPI_VIDEO_NOTIFY_PROBE		0x81#define ACPI_VIDEO_NOTIFY_CYCLE		0x82#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT	0x83#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT	0x84#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS	0x85#define	ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS	0x86#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS	0x87#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS	0x88#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF		0x89#define ACPI_VIDEO_HEAD_INVALID		(~0u - 1)#define ACPI_VIDEO_HEAD_END		(~0u)#define MAX_NAME_LEN	20#define ACPI_VIDEO_DISPLAY_CRT	1#define ACPI_VIDEO_DISPLAY_TV	2#define ACPI_VIDEO_DISPLAY_DVI	3#define ACPI_VIDEO_DISPLAY_LCD	4#define _COMPONENT		ACPI_VIDEO_COMPONENTACPI_MODULE_NAME("video");MODULE_AUTHOR("Bruno Ducrot");MODULE_DESCRIPTION("ACPI Video Driver");MODULE_LICENSE("GPL");static int acpi_video_bus_add(struct acpi_device *device);static int acpi_video_bus_remove(struct acpi_device *device, int type);static const struct acpi_device_id video_device_ids[] = {	{ACPI_VIDEO_HID, 0},	{"", 0},};MODULE_DEVICE_TABLE(acpi, video_device_ids);static struct acpi_driver acpi_video_bus = {	.name = "video",	.class = ACPI_VIDEO_CLASS,	.ids = video_device_ids,	.ops = {		.add = acpi_video_bus_add,		.remove = acpi_video_bus_remove,		},};struct acpi_video_bus_flags {	u8 multihead:1;		/* can switch video heads */	u8 rom:1;		/* can retrieve a video rom */	u8 post:1;		/* can configure the head to */	u8 reserved:5;};struct acpi_video_bus_cap {	u8 _DOS:1;		/*Enable/Disable output switching */	u8 _DOD:1;		/*Enumerate all devices attached to display adapter */	u8 _ROM:1;		/*Get ROM Data */	u8 _GPD:1;		/*Get POST Device */	u8 _SPD:1;		/*Set POST Device */	u8 _VPO:1;		/*Video POST Options */	u8 reserved:2;};struct acpi_video_device_attrib {	u32 display_index:4;	/* A zero-based instance of the Display */	u32 display_port_attachment:4;	/*This field differentiates the display type */	u32 display_type:4;	/*Describe the specific type in use */	u32 vendor_specific:4;	/*Chipset Vendor Specific */	u32 bios_can_detect:1;	/*BIOS can detect the device */	u32 depend_on_vga:1;	/*Non-VGA output device whose power is related to 				   the VGA device. */	u32 pipe_id:3;		/*For VGA multiple-head devices. */	u32 reserved:10;	/*Must be 0 */	u32 device_id_scheme:1;	/*Device ID Scheme */};struct acpi_video_enumerated_device {	union {		u32 int_val;		struct acpi_video_device_attrib attrib;	} value;	struct acpi_video_device *bind_info;};struct acpi_video_bus {	struct acpi_device *device;	u8 dos_setting;	struct acpi_video_enumerated_device *attached_array;	u8 attached_count;	struct acpi_video_bus_cap cap;	struct acpi_video_bus_flags flags;	struct list_head video_device_list;	struct mutex device_list_lock;	/* protects video_device_list */	struct proc_dir_entry *dir;	struct input_dev *input;	char phys[32];	/* for input device */};struct acpi_video_device_flags {	u8 crt:1;	u8 lcd:1;	u8 tvout:1;	u8 dvi:1;	u8 bios:1;	u8 unknown:1;	u8 reserved:2;};struct acpi_video_device_cap {	u8 _ADR:1;		/*Return the unique ID */	u8 _BCL:1;		/*Query list of brightness control levels supported */	u8 _BCM:1;		/*Set the brightness level */	u8 _BQC:1;		/* Get current brightness level */	u8 _DDC:1;		/*Return the EDID for this device */	u8 _DCS:1;		/*Return status of output device */	u8 _DGS:1;		/*Query graphics state */	u8 _DSS:1;		/*Device state set */};struct acpi_video_device_brightness {	int curr;	int count;	int *levels;};struct acpi_video_device {	unsigned long device_id;	struct acpi_video_device_flags flags;	struct acpi_video_device_cap cap;	struct list_head entry;	struct acpi_video_bus *video;	struct acpi_device *dev;	struct acpi_video_device_brightness *brightness;	struct backlight_device *backlight;	struct output_device *output_dev;};/* bus */static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);static struct file_operations acpi_video_bus_info_fops = {	.open = acpi_video_bus_info_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);static struct file_operations acpi_video_bus_ROM_fops = {	.open = acpi_video_bus_ROM_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static int acpi_video_bus_POST_info_open_fs(struct inode *inode,					    struct file *file);static struct file_operations acpi_video_bus_POST_info_fops = {	.open = acpi_video_bus_POST_info_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);static struct file_operations acpi_video_bus_POST_fops = {	.open = acpi_video_bus_POST_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);static struct file_operations acpi_video_bus_DOS_fops = {	.open = acpi_video_bus_DOS_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};/* device */static int acpi_video_device_info_open_fs(struct inode *inode,					  struct file *file);static struct file_operations acpi_video_device_info_fops = {	.open = acpi_video_device_info_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static int acpi_video_device_state_open_fs(struct inode *inode,					   struct file *file);static struct file_operations acpi_video_device_state_fops = {	.open = acpi_video_device_state_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static int acpi_video_device_brightness_open_fs(struct inode *inode,						struct file *file);static struct file_operations acpi_video_device_brightness_fops = {	.open = acpi_video_device_brightness_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static int acpi_video_device_EDID_open_fs(struct inode *inode,					  struct file *file);static struct file_operations acpi_video_device_EDID_fops = {	.open = acpi_video_device_EDID_open_fs,	.read = seq_read,	.llseek = seq_lseek,	.release = single_release,};static char device_decode[][30] = {	"motherboard VGA device",	"PCI VGA device",	"AGP VGA device",	"UNKNOWN",};static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);static void acpi_video_device_rebind(struct acpi_video_bus *video);static void acpi_video_device_bind(struct acpi_video_bus *video,				   struct acpi_video_device *device);static int acpi_video_device_enumerate(struct acpi_video_bus *video);static int acpi_video_switch_output(struct acpi_video_bus *video, int event);static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,			int level);static int acpi_video_device_lcd_get_level_current(			struct acpi_video_device *device,			unsigned long *level);static int acpi_video_get_next_level(struct acpi_video_device *device,				     u32 level_current, u32 event);static void acpi_video_switch_brightness(struct acpi_video_device *device,					 int event);static int acpi_video_device_get_state(struct acpi_video_device *device,			    unsigned long *state);static int acpi_video_output_get(struct output_device *od);static int acpi_video_device_set_state(struct acpi_video_device *device, int state);/*backlight device sysfs support*/static int acpi_video_get_brightness(struct backlight_device *bd){	unsigned long cur_level;	struct acpi_video_device *vd =		(struct acpi_video_device *)bl_get_data(bd);	acpi_video_device_lcd_get_level_current(vd, &cur_level);	return (int) cur_level;}static int acpi_video_set_brightness(struct backlight_device *bd){	int request_level = bd->props.brightness;	struct acpi_video_device *vd =		(struct acpi_video_device *)bl_get_data(bd);	acpi_video_device_lcd_set_level(vd, request_level);	return 0;}static struct backlight_ops acpi_backlight_ops = {	.get_brightness = acpi_video_get_brightness,	.update_status  = acpi_video_set_brightness,};/*video output device sysfs support*/static int acpi_video_output_get(struct output_device *od){	unsigned long state;	struct acpi_video_device *vd =		(struct acpi_video_device *)dev_get_drvdata(&od->dev);	acpi_video_device_get_state(vd, &state);	return (int)state;}static int acpi_video_output_set(struct output_device *od){	unsigned long state = od->request_state;	struct acpi_video_device *vd=		(struct acpi_video_device *)dev_get_drvdata(&od->dev);	return acpi_video_device_set_state(vd, state);}static struct output_properties acpi_output_properties = {	.set_state = acpi_video_output_set,	.get_status = acpi_video_output_get,};/* --------------------------------------------------------------------------                               Video Management   -------------------------------------------------------------------------- *//* device */static intacpi_video_device_query(struct acpi_video_device *device, unsigned long *state){	int status;	status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state);	return status;}static intacpi_video_device_get_state(struct acpi_video_device *device,			    unsigned long *state){	int status;	status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state);	return status;}static intacpi_video_device_set_state(struct acpi_video_device *device, int state){	int status;	union acpi_object arg0 = { ACPI_TYPE_INTEGER };	struct acpi_object_list args = { 1, &arg0 };	unsigned long ret;	arg0.integer.value = state;	status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret);	return status;}static intacpi_video_device_lcd_query_levels(struct acpi_video_device *device,				   union acpi_object **levels){	int status;	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };	union acpi_object *obj;	*levels = NULL;	status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);	if (!ACPI_SUCCESS(status))		return status;	obj = (union acpi_object *)buffer.pointer;	if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {		printk(KERN_ERR PREFIX "Invalid _BCL data\n");		status = -EFAULT;		goto err;	}	*levels = obj;	return 0;      err:	kfree(buffer.pointer);	return status;}static intacpi_video_device_lcd_set_level(struct acpi_video_device *device, int level){	int status = AE_OK;	union acpi_object arg0 = { ACPI_TYPE_INTEGER };	struct acpi_object_list args = { 1, &arg0 };	arg0.integer.value = level;	if (device->cap._BCM)		status = acpi_evaluate_object(device->dev->handle, "_BCM",					      &args, NULL);	device->brightness->curr = level;	return status;}static intacpi_video_device_lcd_get_level_current(struct acpi_video_device *device,					unsigned long *level){	if (device->cap._BQC)		return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,					     level);	*level = device->brightness->curr;	return AE_OK;}static intacpi_video_device_EDID(struct acpi_video_device *device,		       union acpi_object **edid, ssize_t length){	int status;	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };	union acpi_object *obj;	union acpi_object arg0 = { ACPI_TYPE_INTEGER };	struct acpi_object_list args = { 1, &arg0 };	*edid = NULL;	if (!device)		return -ENODEV;	if (length == 128)		arg0.integer.value = 1;	else if (length == 256)		arg0.integer.value = 2;	else		return -EINVAL;	status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);	if (ACPI_FAILURE(status))		return -ENODEV;	obj = buffer.pointer;	if (obj && obj->type == ACPI_TYPE_BUFFER)		*edid = obj;	else {		printk(KERN_ERR PREFIX "Invalid _DDC data\n");		status = -EFAULT;		kfree(obj);	}	return status;}/* bus */static intacpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option){	int status;	unsigned long tmp;	union acpi_object arg0 = { ACPI_TYPE_INTEGER };	struct acpi_object_list args = { 1, &arg0 };	arg0.integer.value = option;	status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp);	if (ACPI_SUCCESS(status))		status = tmp ? (-EINVAL) : (AE_OK);	return status;}static intacpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id){	int status;	status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);	return status;}static intacpi_video_bus_POST_options(struct acpi_video_bus *video,			    unsigned long *options){	int status;	status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options);	*options &= 3;

⌨️ 快捷键说明

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