1#include <KernelExport.h> 2#include <Drivers.h> 3#include <Errors.h> 4#include <string.h> 5 6#include <stdio.h> 7#include <stdlib.h> 8 9#include <ACPI.h> 10 11 12#define DISPLAYCONTROLS_MODULE_NAME "drivers/display/display_controls/driver_v1" 13 14#define DISPLAYCONTROLS_DEVICE_MODULE_NAME "drivers/display/display_controls/device_v1" 15 16/* Base Namespace devices are published to */ 17#define DISPLAYCONTROLS_BASENAME "display/display_controls/%d" 18 19// name of pnp generator of path ids 20#define DISPLAYCONTROLS_PATHID_GENERATOR "displaycontrols/path_id" 21 22 23#define OS_DISPLAY_SWITCH 0 24#define BIOS_DISPLAY_SWITCH 1 25#define LOCK_DISPLAY_SWITCH 2 26#define NOTIFY_DISPLAY_SWITCH 3 27 28#define OS_BRIGHTNESS_CONTROL (1 << 2) 29#define BIOS_BRIGHTNESS_CONTROL (0 << 2) 30 31static device_manager_info *sDeviceManager; 32static acpi_module_info *sAcpi; 33 34 35typedef struct acpi_ns_device_info { 36 device_node *node; 37 acpi_handle acpi_device; 38} displaycontrols_device_info; 39 40 41// #pragma mark - device module API 42 43 44static status_t 45displaycontrols_init_device(void *_cookie, void **cookie) 46{ 47 device_node *node = (device_node *)_cookie; 48 displaycontrols_device_info *device; 49 device_node *parent; 50 51 acpi_objects arguments; 52 acpi_object_type argument; 53 54 const char *path; 55 dprintf("%s: start.\n", __func__); 56 57 58 device = (displaycontrols_device_info *)calloc(1, sizeof(*device)); 59 if (device == NULL) 60 return B_NO_MEMORY; 61 62 device->node = node; 63 if (sDeviceManager->get_attr_string(node, ACPI_DEVICE_PATH_ITEM, &path, false) 64 != B_OK || sAcpi->get_handle(NULL, path, &device->acpi_device) != B_OK) { 65 dprintf("%s: failed to get acpi node.\n", __func__); 66 return B_ERROR; 67 } 68 69 argument.object_type = ACPI_TYPE_INTEGER; 70 argument.data.integer = BIOS_DISPLAY_SWITCH | BIOS_BRIGHTNESS_CONTROL; 71 arguments.count = 1; 72 arguments.pointer = &argument; 73 if (sAcpi->evaluate_object(&device->acpi_device, "_DOS", &arguments, NULL, 0) 74 != B_OK) 75 dprintf("%s: failed to set _DOS %s\n", __func__, path); 76 77 dprintf("%s: done.\n", __func__); 78 *cookie = device; 79 return B_OK; 80} 81 82 83static void 84displaycontrols_uninit_device(void *_cookie) 85{ 86 displaycontrols_device_info *device = (displaycontrols_device_info *)_cookie; 87 free(device); 88} 89 90 91static status_t 92displaycontrols_open(void *_cookie, const char *path, int flags, void** cookie) 93{ 94 displaycontrols_device_info *device = (displaycontrols_device_info *)_cookie; 95 *cookie = device; 96 return B_OK; 97} 98 99 100static status_t 101displaycontrols_read(void* _cookie, off_t position, void *buf, size_t* num_bytes) 102{ 103 return B_ERROR; 104} 105 106 107static status_t 108displaycontrols_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes) 109{ 110 return B_ERROR; 111} 112 113 114static status_t 115displaycontrols_control(void* _cookie, uint32 op, void* arg, size_t len) 116{ 117// displaycontrols_device_info* device = (displaycontrols_device_info*)_cookie; 118 119 return B_ERROR; 120} 121 122 123static status_t 124displaycontrols_close(void* cookie) 125{ 126 return B_OK; 127} 128 129 130static status_t 131displaycontrols_free(void* cookie) 132{ 133 return B_OK; 134} 135 136 137// #pragma mark - driver module API 138 139 140static float 141displaycontrols_support(device_node *parent) 142{ 143 acpi_handle handle, method; 144// acpi_object_type dosType; 145 146 const char *bus; 147 const char *path; 148 uint32 device_type; 149 150 // make sure parent is really the ACPI bus manager 151 if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) 152 return -1; 153 154 if (strcmp(bus, "acpi")) 155 return 0.0; 156 157 if (sDeviceManager->get_attr_string(parent, ACPI_DEVICE_PATH_ITEM, &path, false) != B_OK) 158 return 0.0; 159 160 // check whether it's really a device 161 if (sDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM, &device_type, false) != B_OK 162 || device_type != ACPI_TYPE_DEVICE) { 163 return 0.0; 164 } 165 166 167 if (sAcpi->get_handle(NULL, path, &handle) != B_OK) 168 return 0.0; 169 170 if (sAcpi->get_handle(handle, "_DOD", &method) != B_OK || 171 sAcpi->get_handle(handle, "_DOS", &method) != B_OK) {// || 172// sAcpi->get_type(method, &dosType) != B_OK || 173// dosType != ACPI_TYPE_METHOD) { 174 return 0.0; 175 } 176 177 dprintf("%s: found at bus: %s path: %s\n", __func__, bus, path); 178 return 0.6; 179} 180 181 182static status_t 183displaycontrols_register_device(device_node *node) 184{ 185 device_attr attrs[] = { 186 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "Display Controls" }}, 187 { B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_KEEP_DRIVER_LOADED }}, 188 { NULL } 189 }; 190 191 return sDeviceManager->register_node(node, DISPLAYCONTROLS_MODULE_NAME, attrs, NULL, NULL); 192} 193 194 195static status_t 196displaycontrols_init_driver(device_node *node, void **_driverCookie) 197{ 198 *_driverCookie = node; 199 return B_OK; 200} 201 202 203static void 204displaycontrols_uninit_driver(void *driverCookie) 205{ 206} 207 208 209static status_t 210displaycontrols_register_child_devices(void *_cookie) 211{ 212 device_node *node = (device_node*)_cookie; 213 int path_id; 214 char name[128]; 215 216 path_id = sDeviceManager->create_id(DISPLAYCONTROLS_PATHID_GENERATOR); 217 if (path_id < 0) { 218 dprintf("displaycontrols_register_child_devices: couldn't create a path_id\n"); 219 return B_ERROR; 220 } 221 222 snprintf(name, sizeof(name), DISPLAYCONTROLS_BASENAME, path_id); 223 224 return sDeviceManager->publish_device(node, name, DISPLAYCONTROLS_DEVICE_MODULE_NAME); 225} 226 227 228module_dependency module_dependencies[] = { 229 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager }, 230 { B_ACPI_MODULE_NAME, (module_info **)&sAcpi}, 231 {} 232}; 233 234 235driver_module_info displaycontrols_driver_module = { 236 { 237 DISPLAYCONTROLS_MODULE_NAME, 238 0, 239 NULL 240 }, 241 242 displaycontrols_support, 243 displaycontrols_register_device, 244 displaycontrols_init_driver, 245 displaycontrols_uninit_driver, 246 displaycontrols_register_child_devices, 247 NULL, // rescan 248 NULL, // removed 249}; 250 251 252struct device_module_info displaycontrols_device_module = { 253 { 254 DISPLAYCONTROLS_DEVICE_MODULE_NAME, 255 0, 256 NULL 257 }, 258 259 displaycontrols_init_device, 260 displaycontrols_uninit_device, 261 NULL, 262 263 displaycontrols_open, 264 displaycontrols_close, 265 displaycontrols_free, 266 displaycontrols_read, 267 displaycontrols_write, 268 NULL, 269 displaycontrols_control, 270 271 NULL, 272 NULL 273}; 274 275module_info *modules[] = { 276 (module_info *)&displaycontrols_driver_module, 277 (module_info *)&displaycontrols_device_module, 278 NULL 279}; 280