Subject: [PATCH] [acpi video] Add ability to enable/disable video bus - Add set_int() helper to execute a method and set 1 integer - Add run_dos() with bios_flag and lcd_flag parameter, as interface to the _DOS method for the device - Add video_bus_{enable,disable}() that call run_dos() with the right parameters. - Add ->v_dos to struct acpi_video_bus, and defines for encoding it. Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/video/bus-device.c | 67 +++++++++++++++++++++++++++++++ drivers/acpi/drivers/video/video.h | 13 ++++++ 2 files changed, 80 insertions(+), 0 deletions(-) applies-to: 84b0f9b6f2a0e1820e489912f9717946d3b41572 d8416a078fe8af8643b7309e79d328ab84466049 diff --git a/drivers/acpi/drivers/video/bus-device.c b/drivers/acpi/drivers/video/bus-device.c index a9f7cb8..724ad07 100644 --- a/drivers/acpi/drivers/video/bus-device.c +++ b/drivers/acpi/drivers/video/bus-device.c @@ -40,6 +40,26 @@ static int get_int(struct acpi_dev * ad, } +static int set_int(struct acpi_dev * ad, char * obj, u32 value) +{ + acpi_status status; + union acpi_object arg = { + .type = ACPI_TYPE_INTEGER, + .integer = { + .value = value, + }, + }; + struct acpi_object_list arg_list = { + .count = 1, + .pointer = &arg, + }; + + status = acpi_evaluate_object(ad->acpi_device->handle, + "_DOS", &arg_list, NULL); + return ACPI_SUCCESS(status) ? 0 : -ENODEV; +} + + /** * can_switch - Check if a video bus supports video switching * @ad: The ACPI device representing the video bus @@ -223,3 +243,50 @@ int video_bus_init(struct acpi_video_bus return ret; } + + +/** + * run_dos - Set the video mode by executing _DOS + * @vb: The ACPI video bus + * @bios_flag: Determines how the switch of active display should happen + * @lcd_flag: Determines who controls LCD brightness on AC/DC power change + * + * Possible values for @bios_flag are: + * + * %VIDEO_DOS_BIOS_NO_AUTO Don't let the BIOS do it automatically + * %VIDEO_DOS_BIOS_AUTO BIOS can automatically switch output + * %VIDEO_DOS_BIOS_DGS_LOCK The _DGS value should be locked (meaning?) + * %VIDEO_DOS_BIOS_EVENT Don't auto switch, but raise event + * + * Possible values for @lcd_flag are: + * %VIDEO_DOS_LCD_AUTO BIOS should control brightness level + * %VIDEO_DOS_LCD_NO_AUTO BIOS should *not* control + */ + +static int run_dos(struct acpi_video_bus * vb, u32 bios_flag, u32 lcd_flag) +{ + u32 value = (lcd_flag << 2) | bios_flag; + int ret = 0; + + if (vb->v_can_switch) { + ret = set_int(vb->v_ad, "_DOS", value); + if (!ret) + vb->v_dos = value; + } + return ret; +} + + +int video_bus_enable(struct acpi_video_bus * vb) +{ + int ret; + + return run_dos(vb, VIDEO_DOS_BIOS_AUTO, VIDEO_DOS_LCD_AUTO); +} + +int video_bus_disable(struct acpi_video_bus * vb) +{ + int ret; + + return run_dos(vb, VIDEO_DOS_BIOS_NO_AUTO, VIDEO_DOS_LCD_NO_AUTO); +} diff --git a/drivers/acpi/drivers/video/video.h b/drivers/acpi/drivers/video/video.h index a2988f3..9db2b55 100644 --- a/drivers/acpi/drivers/video/video.h +++ b/drivers/acpi/drivers/video/video.h @@ -16,6 +16,15 @@ ACPI_MODULE_NAME("acpi_video"); #define ACPI_VIDEO_BUS_POST_PCI 0x02 #define ACPI_VIDEO_BUS_POST_AGP 0x04 +#define VIDEO_DOS_BIOS_NO_AUTO 0x00 +#define VIDEO_DOS_BIOS_AUTO 0x01 +#define VIDEO_DOS_BIOS_DGS_LOCK 0x02 +#define VIDEO_DOS_BIOS_EVENT 0x03 + +#define VIDEO_DOS_LCD_AUTO 0x00 +#define VIDEO_DOS_LCD_NO_AUTO 0x01 + + struct acpi_video_bus { int v_can_switch; int v_has_rom; @@ -24,9 +33,13 @@ struct acpi_video_bus { int v_post_options; int v_post_id; + u32 v_dos; + struct acpi_dev * v_ad; }; extern int video_bus_test(struct acpi_dev * ad); extern int video_bus_init(struct acpi_video_bus * vb); +extern int video_bus_enable(struct acpi_video_bus * vb); +extern int video_bus_disable(struct acpi_video_bus * vb); --- 0.99.9.GIT