📄 video.c
字号:
return status;}/* * Arg: * video : video bus device pointer * bios_flag : * 0. The system BIOS should NOT automatically switch(toggle) * the active display output. * 1. The system BIOS should automatically switch (toggle) the * active display output. No switch event. * 2. The _DGS value should be locked. * 3. The system BIOS should not automatically switch (toggle) the * active display output, but instead generate the display switch * event notify code. * lcd_flag : * 0. The system BIOS should automatically control the brightness level * of the LCD when the power changes from AC to DC * 1. The system BIOS should NOT automatically control the brightness * level of the LCD when the power changes from AC to DC. * Return Value: * -1 wrong arg. */static intacpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag){ acpi_integer status = 0; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) { status = -1; goto Failed; } arg0.integer.value = (lcd_flag << 2) | bios_flag; video->dos_setting = arg0.integer.value; acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL); Failed: return status;}/* * Arg: * device : video output device (LCD, CRT, ..) * * Return Value: * None * * Find out all required AML methods defined under the output * device. */static void acpi_video_device_find_cap(struct acpi_video_device *device){ acpi_handle h_dummy1; int i; u32 max_level = 0; union acpi_object *obj = NULL; struct acpi_video_device_brightness *br = NULL; memset(&device->cap, 0, sizeof(device->cap)); if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { device->cap._ADR = 1; } if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) { device->cap._BCL = 1; } if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { device->cap._BCM = 1; } if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) device->cap._BQC = 1; if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { device->cap._DDC = 1; } if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) { device->cap._DCS = 1; } if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) { device->cap._DGS = 1; } if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) { device->cap._DSS = 1; } if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { if (obj->package.count >= 2) { int count = 0; union acpi_object *o; br = kzalloc(sizeof(*br), GFP_KERNEL); if (!br) { printk(KERN_ERR "can't allocate memory\n"); } else { br->levels = kmalloc(obj->package.count * sizeof *(br->levels), GFP_KERNEL); if (!br->levels) goto out; for (i = 0; i < obj->package.count; i++) { o = (union acpi_object *)&obj->package. elements[i]; if (o->type != ACPI_TYPE_INTEGER) { printk(KERN_ERR PREFIX "Invalid data\n"); continue; } br->levels[count] = (u32) o->integer.value; if (br->levels[count] > max_level) max_level = br->levels[count]; count++; } out: if (count < 2) { kfree(br->levels); kfree(br); } else { br->count = count; device->brightness = br; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); } } } } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n")); } kfree(obj); if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ unsigned long tmp; static int count = 0; char *name; name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); if (!name) return; sprintf(name, "acpi_video%d", count++); acpi_video_device_lcd_get_level_current(device, &tmp); device->backlight = backlight_device_register(name, NULL, device, &acpi_backlight_ops); device->backlight->props.max_brightness = max_level; device->backlight->props.brightness = (int)tmp; backlight_update_status(device->backlight); kfree(name); } if (device->cap._DCS && device->cap._DSS){ static int count = 0; char *name; name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); if (!name) return; sprintf(name, "acpi_video%d", count++); device->output_dev = video_output_register(name, NULL, device, &acpi_output_properties); kfree(name); } return;}/* * Arg: * device : video output device (VGA) * * Return Value: * None * * Find out all required AML methods defined under the video bus device. */static void acpi_video_bus_find_cap(struct acpi_video_bus *video){ acpi_handle h_dummy1; memset(&video->cap, 0, sizeof(video->cap)); if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { video->cap._DOS = 1; } if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) { video->cap._DOD = 1; } if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) { video->cap._ROM = 1; } if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) { video->cap._GPD = 1; } if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) { video->cap._SPD = 1; } if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) { video->cap._VPO = 1; }}/* * Check whether the video bus device has required AML method to * support the desired features */static int acpi_video_bus_check(struct acpi_video_bus *video){ acpi_status status = -ENOENT; if (!video) return -EINVAL; /* Since there is no HID, CID and so on for VGA driver, we have * to check well known required nodes. */ /* Does this device support video switching? */ if (video->cap._DOS) { video->flags.multihead = 1; status = 0; } /* Does this device support retrieving a video ROM? */ if (video->cap._ROM) { video->flags.rom = 1; status = 0; } /* Does this device support configuring which video device to POST? */ if (video->cap._GPD && video->cap._SPD && video->cap._VPO) { video->flags.post = 1; status = 0; } return status;}/* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */static struct proc_dir_entry *acpi_video_dir;/* video devices */static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset){ struct acpi_video_device *dev = seq->private; if (!dev) goto end; seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id); seq_printf(seq, "type: "); if (dev->flags.crt) seq_printf(seq, "CRT\n"); else if (dev->flags.lcd) seq_printf(seq, "LCD\n"); else if (dev->flags.tvout) seq_printf(seq, "TVOUT\n"); else if (dev->flags.dvi) seq_printf(seq, "DVI\n"); else seq_printf(seq, "UNKNOWN\n"); seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no"); end: return 0;}static intacpi_video_device_info_open_fs(struct inode *inode, struct file *file){ return single_open(file, acpi_video_device_info_seq_show, PDE(inode)->data);}static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset){ int status; struct acpi_video_device *dev = seq->private; unsigned long state; if (!dev) goto end; status = acpi_video_device_get_state(dev, &state); seq_printf(seq, "state: "); if (ACPI_SUCCESS(status)) seq_printf(seq, "0x%02lx\n", state); else seq_printf(seq, "<not supported>\n"); status = acpi_video_device_query(dev, &state); seq_printf(seq, "query: "); if (ACPI_SUCCESS(status)) seq_printf(seq, "0x%02lx\n", state); else seq_printf(seq, "<not supported>\n"); end: return 0;}static intacpi_video_device_state_open_fs(struct inode *inode, struct file *file){ return single_open(file, acpi_video_device_state_seq_show, PDE(inode)->data);}static ssize_tacpi_video_device_write_state(struct file *file, const char __user * buffer, size_t count, loff_t * data){ int status; struct seq_file *m = file->private_data; struct acpi_video_device *dev = m->private; char str[12] = { 0 }; u32 state = 0; if (!dev || count + 1 > sizeof str) return -EINVAL; if (copy_from_user(str, buffer, count)) return -EFAULT; str[count] = 0; state = simple_strtoul(str, NULL, 0); state &= ((1ul << 31) | (1ul << 30) | (1ul << 0)); status = acpi_video_device_set_state(dev, state); if (status) return -EFAULT; return count;}static intacpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset){ struct acpi_video_device *dev = seq->private; int i; if (!dev || !dev->brightness) { seq_printf(seq, "<not supported>\n"); return 0; } seq_printf(seq, "levels: "); for (i = 0; i < dev->brightness->count; i++) seq_printf(seq, " %d", dev->brightness->levels[i]); seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); return 0;}static intacpi_video_device_brightness_open_fs(struct inode *inode, struct file *file){ return single_open(file, acpi_video_device_brightness_seq_show, PDE(inode)->data);}static ssize_tacpi_video_device_write_brightness(struct file *file, const char __user * buffer, size_t count, loff_t * data){ struct seq_file *m = file->private_data; struct acpi_video_device *dev = m->private; char str[5] = { 0 }; unsigned int level = 0; int i; if (!dev || !dev->brightness || count + 1 > sizeof str) return -EINVAL; if (copy_from_user(str, buffer, count)) return -EFAULT; str[count] = 0; level = simple_strtoul(str, NULL, 0); if (level > 100) return -EFAULT; /* validate through the list of available levels */ for (i = 0; i < dev->brightness->count; i++) if (level == dev->brightness->levels[i]) { if (ACPI_SUCCESS (acpi_video_device_lcd_set_level(dev, level))) dev->brightness->curr = level; break; } return count;}static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset){ struct acpi_video_device *dev = seq->private; int status; int i; union acpi_object *edid = NULL; if (!dev) goto out; status = acpi_video_device_EDID(dev, &edid, 128); if (ACPI_FAILURE(status)) { status = acpi_video_device_EDID(dev, &edid, 256); } if (ACPI_FAILURE(status)) { goto out; } if (edid && edid->type == ACPI_TYPE_BUFFER) { for (i = 0; i < edid->buffer.length; i++) seq_putc(seq, edid->buffer.pointer[i]); } out: if (!edid) seq_printf(seq, "<not supported>\n"); else kfree(edid); return 0;}static intacpi_video_device_EDID_open_fs(struct inode *inode, struct file *file){ return single_open(file, acpi_video_device_EDID_seq_show, PDE(inode)->data);}static int acpi_video_device_add_fs(struct acpi_device *device){ struct proc_dir_entry *entry = NULL; struct acpi_video_device *vid_dev; if (!device) return -ENODEV; vid_dev = acpi_driver_data(device); if (!vid_dev) return -ENODEV; if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), vid_dev->video->dir); if (!acpi_device_dir(device)) return -ENODEV; acpi_device_dir(device)->owner = THIS_MODULE; } /* 'info' [R] */ entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); if (!entry) return -ENODEV; else { entry->proc_fops = &acpi_video_device_info_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } /* 'state' [R/W] */ entry = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR, acpi_device_dir(device)); if (!entry) return -ENODEV; else { acpi_video_device_state_fops.write = acpi_video_device_write_state; entry->proc_fops = &acpi_video_device_state_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } /* 'brightness' [R/W] */ entry = create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR, acpi_device_dir(device)); if (!entry) return -ENODEV; else { acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness; entry->proc_fops = &acpi_video_device_brightness_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } /* 'EDID' [R] */ entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device)); if (!entry) return -ENODEV;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -