btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / add-ons / kernel / drivers / display / display_adapter.cpp
blob841253f295e7692a0cd625bcb3f3dab243e8ead9
1 #include "display_adapter.h"
4 typedef struct acpi_ns_device_info {
5 device_node *node;
6 acpi_handle acpi_device;
7 } displayadapter_device_info;
10 device_manager_info *gDeviceManager = NULL;
11 acpi_module_info *gAcpi = NULL;
16 TODO: ACPI Spec 5 Appendix B: Implement:
17 _DOS Method to control display output switching
18 ( _DOD Method to retrieve information about child output devices
19 - You can already do this by listing child devices )
20 _ROM Method to retrieve the ROM image for this device
21 _GPD Method for determining which VGA device will post
22 _SPD Method for controlling which VGA device will post
23 _VPO Method for determining the post options
25 Display cycling notifications
30 // #pragma mark - device module API
33 static status_t
34 displayadapter_init_device(void *_cookie, void **cookie)
36 device_node *node = (device_node *)_cookie;
37 displayadapter_device_info *device;
38 // device_node *parent;
40 // acpi_objects arguments;
41 // acpi_object_type argument;
43 const char *path;
44 dprintf("%s: start.\n", __func__);
47 device = (displayadapter_device_info *)calloc(1, sizeof(*device));
48 if (device == NULL)
49 return B_NO_MEMORY;
51 device->node = node;
52 if (gDeviceManager->get_attr_string(node, ACPI_DEVICE_PATH_ITEM, &path,
53 false) != B_OK
54 || gAcpi->get_handle(NULL, path, &device->acpi_device) != B_OK) {
55 dprintf("%s: failed to get acpi node.\n", __func__);
56 free(device);
57 return B_ERROR;
60 argument.object_type = ACPI_TYPE_INTEGER;
61 argument.integer.integer = BIOS_DISPLAY_SWITCH | BIOS_BRIGHTNESS_CONTROL;
62 arguments.count = 1;
63 arguments.pointer = &argument;
64 if (gAcpi->evaluate_object(&device->acpi_device, "_DOS", &arguments, NULL,
65 0) != B_OK)
66 dprintf("%s: failed to set _DOS %s\n", __func__, path);
68 dprintf("%s: done.\n", __func__);
70 *cookie = device;
71 return B_OK;
75 static void
76 displayadapter_uninit_device(void *_cookie)
78 displayadapter_device_info *device = (displayadapter_device_info *)_cookie;
79 free(device);
83 static status_t
84 displayadapter_open(void *_cookie, const char *path, int flags, void** cookie)
86 displayadapter_device_info *device = (displayadapter_device_info *)_cookie;
87 *cookie = device;
88 return B_OK;
92 static status_t
93 displayadapter_read(void* _cookie, off_t position, void *buf, size_t* num_bytes)
95 return B_ERROR;
99 static status_t
100 displayadapter_write(void* cookie, off_t position, const void* buffer,
101 size_t* num_bytes)
103 return B_ERROR;
107 static status_t
108 displayadapter_control(void* _cookie, uint32 op, void* arg, size_t len)
110 // displayadapter_device_info* device = (displayadapter_device_info*)_cookie;
112 return B_ERROR;
116 static status_t
117 displayadapter_close(void* cookie)
119 return B_OK;
123 static status_t
124 displayadapter_free(void* cookie)
126 return B_OK;
130 // #pragma mark - driver module API
133 static float
134 displayadapter_support(device_node *parent)
136 acpi_handle handle, method;
137 // acpi_object_type dosType;
139 const char *bus;
140 const char *path;
141 uint32 device_type;
143 // make sure parent is really the ACPI bus manager
144 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
145 return -1;
147 if (strcmp(bus, "acpi"))
148 return 0.0;
150 if (gDeviceManager->get_attr_string(parent, ACPI_DEVICE_PATH_ITEM, &path,
151 false) != B_OK)
152 return 0.0;
154 // check whether it's really a device
155 if (gDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM,
156 &device_type, false) != B_OK
157 || device_type != ACPI_TYPE_DEVICE) {
158 return 0.0;
162 if (gAcpi->get_handle(NULL, path, &handle) != B_OK)
163 return 0.0;
165 if (gAcpi->get_handle(handle, "_DOD", &method) != B_OK ||
166 gAcpi->get_handle(handle, "_DOS", &method) != B_OK) {// ||
167 // sAcpi->get_type(method, &dosType) != B_OK ||
168 // dosType != ACPI_TYPE_METHOD) {
169 return 0.0;
172 dprintf("%s: found at bus: %s path: %s\n", __func__, bus, path);
173 return 0.6;
177 static status_t
178 register_displays(const char *parentName, device_node *node)
180 acpi_handle acpiHandle;
181 const char *path;
182 device_node *parent = gDeviceManager->get_parent_node(node);
183 if (gDeviceManager->get_attr_string(parent, ACPI_DEVICE_PATH_ITEM, &path,
184 false) != B_OK
185 || gAcpi->get_handle(NULL, path, &acpiHandle) != B_OK) {
186 dprintf("%s: failed to get acpi node.\n", __func__);
187 gDeviceManager->put_node(parent);
188 return B_ERROR;
191 //get list of ids from _DOD
192 acpi_object_type *pkgData = (acpi_object_type *)malloc(128);
193 if (pkgData == NULL)
194 return B_ERROR;
196 status_t status = gAcpi->evaluate_object(acpiHandle, "_DOD", NULL, pkgData,
197 128);
198 if (status != B_OK || pkgData->object_type != ACPI_TYPE_PACKAGE) {
199 dprintf("%s: fail. %ld %lu\n", __func__, status, pkgData->object_type);
200 free(pkgData);
201 return status;
204 acpi_object_type *displayIDs = pkgData->package.objects;
205 for (uint32 i = 0; i < pkgData->package.count; i++) {
206 dprintf("Display ID = %lld\n", displayIDs[i].integer.integer);
209 acpi_object_type result;
210 acpi_handle child = NULL;
211 while (gAcpi->get_next_object(ACPI_TYPE_DEVICE, acpiHandle, &child)
212 == B_OK) {
213 char name[5] = {0};
214 //TODO: HARDCODED type.
215 if(gAcpi->get_name(child, 1, name, 5) == B_OK)
216 dprintf("name: %s\n", name);
217 if (gAcpi->evaluate_object(child, "_ADR", NULL, &result, sizeof(result))
218 != B_OK)
219 continue;
221 dprintf("Child _adr %llu\n", result.integer.integer);
222 uint32 i;
223 for (i = 0; i < pkgData->package.count; i++)
224 if (displayIDs[i].integer.integer == result.integer.integer) break;
226 if (i == pkgData->package.count) continue;
228 device_attr attrs[] = {
229 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: name }},
230 { B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_KEEP_DRIVER_LOADED }},
231 { NULL }
235 device_node* deviceNode;
236 gDeviceManager->register_node(node, DISPLAY_DEVICE_MODULE_NAME, attrs,
237 NULL, &deviceNode);
239 char deviceName[128];
240 snprintf(deviceName, sizeof(deviceName), "%s/%s", parentName, name);
241 gDeviceManager->publish_device(parent, deviceName,
242 DISPLAY_DEVICE_MODULE_NAME);
245 gDeviceManager->put_node(parent);
246 free(pkgData);
247 return B_OK;
251 static status_t
252 displayadapter_register_device(device_node *node)
254 device_attr attrs[] = {
255 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "Display Adapter" }},
256 { B_DEVICE_FLAGS, B_UINT32_TYPE, {
257 ui32: B_KEEP_DRIVER_LOADED | B_FIND_MULTIPLE_CHILDREN }},
258 { NULL }
261 return gDeviceManager->register_node(node, DISPLAYADAPTER_MODULE_NAME,
262 attrs, NULL, NULL);
266 static status_t
267 displayadapter_init_driver(device_node *node, void **_driverCookie)
269 *_driverCookie = node;
270 return B_OK;
274 static void
275 displayadapter_uninit_driver(void *driverCookie)
280 static status_t
281 displayadapter_register_child_devices(void *_cookie)
283 device_node *node = (device_node*)_cookie;
285 int path_id = gDeviceManager->create_id(DISPLAYADAPTER_PATHID_GENERATOR);
286 if (path_id < 0) {
287 dprintf("displayadapter_register_child_devices: error creating path\n");
288 return B_ERROR;
291 char name[128];
292 snprintf(name, sizeof(name), DISPLAYADAPTER_BASENAME, path_id);
293 status_t status = gDeviceManager->publish_device(node, name,
294 DISPLAYADAPTER_DEVICE_MODULE_NAME);
296 if (status == B_OK)
297 register_displays(name, node);
299 return status;
303 module_dependency module_dependencies[] = {
304 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
305 { B_ACPI_MODULE_NAME, (module_info **)&gAcpi},
310 driver_module_info displayadapter_driver_module = {
312 DISPLAYADAPTER_MODULE_NAME,
314 NULL
317 displayadapter_support,
318 displayadapter_register_device,
319 displayadapter_init_driver,
320 displayadapter_uninit_driver,
321 displayadapter_register_child_devices,
322 NULL, // rescan
323 NULL, // removed
327 device_module_info displayadapter_device_module = {
329 DISPLAYADAPTER_DEVICE_MODULE_NAME,
331 NULL
334 displayadapter_init_device,
335 displayadapter_uninit_device,
336 NULL,
338 displayadapter_open,
339 displayadapter_close,
340 displayadapter_free,
341 displayadapter_read,
342 displayadapter_write,
343 NULL,
344 displayadapter_control,
346 NULL,
347 NULL
351 module_info *modules[] = {
352 (module_info *)&display_device_module,
353 (module_info *)&displayadapter_device_module,
354 (module_info *)&displayadapter_driver_module,
355 NULL