1 // SPDX-License-Identifier: MIT
3 * Copyright (C) 2020 Red Hat, Inc.
6 * Hans de Goede <hdegoede@redhat.com>
9 #include <linux/acpi.h>
10 #include <drm/drm_privacy_screen_machine.h>
13 static struct drm_privacy_screen_lookup arch_lookup
;
15 struct arch_init_data
{
16 struct drm_privacy_screen_lookup lookup
;
20 #if IS_ENABLED(CONFIG_THINKPAD_ACPI)
21 static acpi_status __init
acpi_set_handle(acpi_handle handle
, u32 level
,
22 void *context
, void **return_value
)
24 *(acpi_handle
*)return_value
= handle
;
25 return AE_CTRL_TERMINATE
;
28 static bool __init
detect_thinkpad_privacy_screen(void)
30 union acpi_object obj
= { .type
= ACPI_TYPE_INTEGER
};
31 struct acpi_object_list args
= { .count
= 1, .pointer
= &obj
, };
32 acpi_handle ec_handle
= NULL
;
33 unsigned long long output
;
39 /* Get embedded-controller handle */
40 status
= acpi_get_devices("PNP0C09", acpi_set_handle
, NULL
, &ec_handle
);
41 if (ACPI_FAILURE(status
) || !ec_handle
)
44 /* And call the privacy-screen get-status method */
45 status
= acpi_evaluate_integer(ec_handle
, "HKEY.GSSS", &args
, &output
);
46 if (ACPI_FAILURE(status
))
49 return (output
& 0x10000) ? true : false;
53 #if IS_ENABLED(CONFIG_CHROMEOS_PRIVACY_SCREEN)
54 static bool __init
detect_chromeos_privacy_screen(void)
56 return acpi_dev_present("GOOG0010", NULL
, -1);
60 static const struct arch_init_data arch_init_data
[] __initconst
= {
61 #if IS_ENABLED(CONFIG_THINKPAD_ACPI)
66 .provider
= "privacy_screen-thinkpad_acpi",
68 .detect
= detect_thinkpad_privacy_screen
,
71 #if IS_ENABLED(CONFIG_CHROMEOS_PRIVACY_SCREEN)
76 .provider
= "privacy_screen-GOOG0010:00",
78 .detect
= detect_chromeos_privacy_screen
,
83 void __init
drm_privacy_screen_lookup_init(void)
87 for (i
= 0; i
< ARRAY_SIZE(arch_init_data
); i
++) {
88 if (!arch_init_data
[i
].detect())
91 pr_info("Found '%s' privacy-screen provider\n",
92 arch_init_data
[i
].lookup
.provider
);
94 /* Make a copy because arch_init_data is __initconst */
95 arch_lookup
= arch_init_data
[i
].lookup
;
96 drm_privacy_screen_lookup_add(&arch_lookup
);
101 void drm_privacy_screen_lookup_exit(void)
103 if (arch_lookup
.provider
)
104 drm_privacy_screen_lookup_remove(&arch_lookup
);
106 #endif /* ifdef CONFIG_X86 */