Subject: [PATCH] [acpi video] Add interface for display switching - Add video_switch_{prev,next}() for cycling through output choices - Add find_active() and get_video_dev() helpers for those functions Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/video/bus-device.c | 81 +++++++++++++++++++++++++++++++ drivers/acpi/drivers/video/video.h | 3 + 2 files changed, 84 insertions(+), 0 deletions(-) applies-to: 795ec5ec72e11288fbb3db463873595b4b649a14 852029b9e620b73277f46964c3e8557643aeca33 diff --git a/drivers/acpi/drivers/video/bus-device.c b/drivers/acpi/drivers/video/bus-device.c index c1f5172..80b76c4 100644 --- a/drivers/acpi/drivers/video/bus-device.c +++ b/drivers/acpi/drivers/video/bus-device.c @@ -462,6 +462,36 @@ int video_dev_get_state(struct acpi_vide EXPORT_SYMBOL_GPL(video_dev_get_state); +static int find_active(struct acpi_video_bus * vb) +{ + u32 output_state, graphics_state; + int ret; + int i; + + for (i = 0; i < vb->v_dev_num; i++) { + if (vb->v_dev[i].v_device) { + ret = video_dev_get_state(vb->v_dev[i].v_device, + &output_state, + &graphics_state); + if (ret) + continue; + if (output_state & VIDEO_OUTPUT_ACTIVE) + return i; + } + } + return -1; +} + +static struct acpi_video_dev * get_video_dev(struct acpi_video_bus * vb, int index) +{ + if (index >= vb->v_dev_num) + index = 0; + else if (index < 0) + index = vb->v_dev_num - 1; + return vb->v_dev[index].v_device; +} + + /** * video_dev_set_state - Set the device state via _DCS * @vd: The ACPI video device @@ -475,3 +505,54 @@ int video_dev_set_state(struct acpi_vide EXPORT_SYMBOL_GPL(video_dev_set_state); + +int video_switch_next(struct acpi_video_bus * vb) +{ + struct acpi_video_dev * vd, * next_vd; + int index; + + index = find_active(vb); + if (index < 0) + return -ENODEV; + + vd = get_video_dev(vb, index); + next_vd = get_video_dev(vb, index + 1); + + /* + * Turn off this device + */ + video_dev_set_state(vd, 0); + + /* + * Enable the next one in line + */ + video_dev_set_state(next_vd, 0x80000001); + + return 0; +} + +int video_switch_prev(struct acpi_video_bus * vb) +{ + struct acpi_video_dev * vd, * prev_vd; + int index; + + index = find_active(vb); + if (index < 0) + return -ENODEV; + + vd = get_video_dev(vb, index); + prev_vd = get_video_dev(vb, index - 1); + + /* + * Turn off this device + */ + video_dev_set_state(vd, 0); + + /* + * Enable the next one in line + */ + video_dev_set_state(prev_vd, 0x80000001); + + return 0; +} + diff --git a/drivers/acpi/drivers/video/video.h b/drivers/acpi/drivers/video/video.h index 41c0e92..77bfad8 100644 --- a/drivers/acpi/drivers/video/video.h +++ b/drivers/acpi/drivers/video/video.h @@ -122,3 +122,6 @@ extern int video_bus_enable(struct acpi_ extern int video_bus_disable(struct acpi_video_bus * vb); extern int video_bus_set_post(struct acpi_video_bus * vb, u32 post); extern int video_bus_dos_set(struct acpi_video_bus * vb, u32 value); + +extern int video_switch_next(struct acpi_video_bus * vb); +extern int video_switch_prev(struct acpi_video_bus * vb); --- 0.99.9.GIT