1/** 2 * \file 3 * \brief ACPI video hacks 4 */ 5 6/* 7 * Copyright (c) 2009, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <barrelfish/barrelfish.h> 17#include <acpi.h> 18 19#include "acpi_shared.h" 20#include "acpi_debug.h" 21 22static ACPI_STATUS walk_video_device(ACPI_HANDLE handle, UINT32 level, 23 void *context, void **dummy) 24{ 25 ACPI_OBJECT_LIST ArgList; 26 ACPI_OBJECT Arg; 27 ACPI_STATUS as; 28 char namebuf[128]; 29 ACPI_BUFFER namebufobj = {.Length = sizeof(namebuf), .Pointer = namebuf}; 30 31 /* get the node's name */ 32 as = AcpiGetName(handle, ACPI_FULL_PATHNAME, &namebufobj); 33 if (ACPI_FAILURE(as)) { 34 return as; 35 } 36 assert(namebufobj.Pointer == namebuf); 37 38#if 1 39 /* Execute the _DOS method (Enable/Disable Output Switching) B.4.1 */ 40 ArgList.Count = 1; 41 ArgList.Pointer = &Arg; 42 Arg.Type = ACPI_TYPE_INTEGER; 43 Arg.Integer.Value = 0x1; /* automatically switch outputs */ 44 as = AcpiEvaluateObject(handle, "_DOS", &ArgList, NULL); 45 if (ACPI_SUCCESS(as)) { 46 ACPI_DEBUG("%s: successfully enabled video output switching\n", namebuf); 47 } 48#endif 49 50 /* Execute the _DOD method if present (enumerate all devices, B.4.2 */ 51 char packagebuf[1024]; 52 ACPI_BUFFER retbuf = {.Length = sizeof(packagebuf), .Pointer = packagebuf}; 53 as = AcpiEvaluateObjectTyped(handle, "_DOD", NULL, &retbuf, ACPI_TYPE_PACKAGE); 54 if (ACPI_SUCCESS(as)) { 55 ACPI_DEBUG("called %s._DOD ok\n", namebuf); 56 } else if (as != AE_NOT_FOUND) { 57 ACPI_DEBUG("error executing _DOD method on %s: 0x%"PRIx32"\n", namebuf, as); 58 } 59 60 /* Execute the _DCS method if present (output device status) B.6.6 */ 61 ACPI_INTEGER retval; 62 as = acpi_eval_integer(handle, "_DCS", &retval); 63 if (ACPI_FAILURE(as)) { 64 if (as != AE_NOT_FOUND) { 65 ACPI_DEBUG("error executing _DCS method on %s: 0x%"PRIx32"\n", namebuf, as); 66 } 67 return AE_OK; // skip the rest 68 } 69 70 ACPI_DEBUG("%s: current video state is 0x%"PRIx64"\n", namebuf, retval); 71 72 /* if connector exists and is ready to switch, enable it! */ 73 if ((strstr(namebuf, "CRT0") || strstr(namebuf, "LCD0")) 74 && (retval & 0xf) == 0xd) { 75 ArgList.Count = 1; 76 ArgList.Pointer = &Arg; 77 Arg.Type = ACPI_TYPE_INTEGER; 78 Arg.Integer.Value = 0x80000001; 79 as = AcpiEvaluateObject(handle, "_DSS", &ArgList, NULL); 80 if (ACPI_SUCCESS(as)) { 81 ACPI_DEBUG("%s: successfully enabled video output\n", namebuf); 82 } else { 83 ACPI_DEBUG("%s: enabling video output failed: 0x%"PRIx32"\n", namebuf, as); 84 } 85 } 86 87 return AE_OK; 88} 89 90// XXX: enable video output switching 91void acpi_arch_video_init(void) 92{ 93 ACPI_STATUS as; 94 95 /* find all devices with a _DOS method and call it */ 96 ACPI_DEBUG("Walking for video devices\n"); 97 //as = AcpiGetDevices(NULL, walk_video_device, NULL, NULL); 98 as = AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 99 walk_video_device, walk_video_device, NULL, NULL); 100 assert(ACPI_SUCCESS(as)); 101} 102