1 #include "display_adapter.h"
4 typedef struct acpi_ns_device_info
{
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
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;
44 dprintf("%s: start.\n", __func__
);
47 device
= (displayadapter_device_info
*)calloc(1, sizeof(*device
));
52 if (gDeviceManager
->get_attr_string(node
, ACPI_DEVICE_PATH_ITEM
, &path
,
54 || gAcpi
->get_handle(NULL
, path
, &device
->acpi_device
) != B_OK
) {
55 dprintf("%s: failed to get acpi node.\n", __func__
);
60 argument.object_type = ACPI_TYPE_INTEGER;
61 argument.integer.integer = BIOS_DISPLAY_SWITCH | BIOS_BRIGHTNESS_CONTROL;
63 arguments.pointer = &argument;
64 if (gAcpi->evaluate_object(&device->acpi_device, "_DOS", &arguments, NULL,
66 dprintf("%s: failed to set _DOS %s\n", __func__, path);
68 dprintf("%s: done.\n", __func__);
76 displayadapter_uninit_device(void *_cookie
)
78 displayadapter_device_info
*device
= (displayadapter_device_info
*)_cookie
;
84 displayadapter_open(void *_cookie
, const char *path
, int flags
, void** cookie
)
86 displayadapter_device_info
*device
= (displayadapter_device_info
*)_cookie
;
93 displayadapter_read(void* _cookie
, off_t position
, void *buf
, size_t* num_bytes
)
100 displayadapter_write(void* cookie
, off_t position
, const void* buffer
,
108 displayadapter_control(void* _cookie
, uint32 op
, void* arg
, size_t len
)
110 // displayadapter_device_info* device = (displayadapter_device_info*)_cookie;
117 displayadapter_close(void* cookie
)
124 displayadapter_free(void* cookie
)
130 // #pragma mark - driver module API
134 displayadapter_support(device_node
*parent
)
136 acpi_handle handle
, method
;
137 // acpi_object_type dosType;
143 // make sure parent is really the ACPI bus manager
144 if (gDeviceManager
->get_attr_string(parent
, B_DEVICE_BUS
, &bus
, false))
147 if (strcmp(bus
, "acpi"))
150 if (gDeviceManager
->get_attr_string(parent
, ACPI_DEVICE_PATH_ITEM
, &path
,
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
) {
162 if (gAcpi
->get_handle(NULL
, path
, &handle
) != B_OK
)
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) {
172 dprintf("%s: found at bus: %s path: %s\n", __func__
, bus
, path
);
178 register_displays(const char *parentName
, device_node
*node
)
180 acpi_handle acpiHandle
;
182 device_node
*parent
= gDeviceManager
->get_parent_node(node
);
183 if (gDeviceManager
->get_attr_string(parent
, ACPI_DEVICE_PATH_ITEM
, &path
,
185 || gAcpi
->get_handle(NULL
, path
, &acpiHandle
) != B_OK
) {
186 dprintf("%s: failed to get acpi node.\n", __func__
);
187 gDeviceManager
->put_node(parent
);
191 //get list of ids from _DOD
192 acpi_object_type
*pkgData
= (acpi_object_type
*)malloc(128);
196 status_t status
= gAcpi
->evaluate_object(acpiHandle
, "_DOD", NULL
, pkgData
,
198 if (status
!= B_OK
|| pkgData
->object_type
!= ACPI_TYPE_PACKAGE
) {
199 dprintf("%s: fail. %ld %lu\n", __func__
, status
, pkgData
->object_type
);
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
)
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
))
221 dprintf("Child _adr %llu\n", result
.integer
.integer
);
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
}},
235 device_node
* deviceNode
;
236 gDeviceManager
->register_node(node
, DISPLAY_DEVICE_MODULE_NAME
, attrs
,
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
);
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
}},
261 return gDeviceManager
->register_node(node
, DISPLAYADAPTER_MODULE_NAME
,
267 displayadapter_init_driver(device_node
*node
, void **_driverCookie
)
269 *_driverCookie
= node
;
275 displayadapter_uninit_driver(void *driverCookie
)
281 displayadapter_register_child_devices(void *_cookie
)
283 device_node
*node
= (device_node
*)_cookie
;
285 int path_id
= gDeviceManager
->create_id(DISPLAYADAPTER_PATHID_GENERATOR
);
287 dprintf("displayadapter_register_child_devices: error creating path\n");
292 snprintf(name
, sizeof(name
), DISPLAYADAPTER_BASENAME
, path_id
);
293 status_t status
= gDeviceManager
->publish_device(node
, name
,
294 DISPLAYADAPTER_DEVICE_MODULE_NAME
);
297 register_displays(name
, node
);
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
,
317 displayadapter_support
,
318 displayadapter_register_device
,
319 displayadapter_init_driver
,
320 displayadapter_uninit_driver
,
321 displayadapter_register_child_devices
,
327 device_module_info displayadapter_device_module
= {
329 DISPLAYADAPTER_DEVICE_MODULE_NAME
,
334 displayadapter_init_device
,
335 displayadapter_uninit_device
,
339 displayadapter_close
,
342 displayadapter_write
,
344 displayadapter_control
,
351 module_info
*modules
[] = {
352 (module_info
*)&display_device_module
,
353 (module_info
*)&displayadapter_device_module
,
354 (module_info
*)&displayadapter_driver_module
,