Merge branch 'acpi-video'
* acpi-video: ACPI / video: driver must be registered before checking for keypresses ACPI / video: Add a quirk to force acpi-video backlight on SAMSUNG 530U4E/540U4E ACPI / video: Add quirks for the Dell Vostro V131 ACPI / video: Add a module option to disable the reporting of keypresses thinkpad_acpi: Use acpi_video_handles_brightness_key_presses() dell-wmi: Use acpi_video_handles_brightness_key_presses() ACPI / video: Add a acpi_video_handles_brightness_key_presses() helper
This commit is contained in:
commit
b12745cce2
|
@ -77,14 +77,21 @@ module_param(allow_duplicates, bool, 0644);
|
||||||
static int disable_backlight_sysfs_if = -1;
|
static int disable_backlight_sysfs_if = -1;
|
||||||
module_param(disable_backlight_sysfs_if, int, 0444);
|
module_param(disable_backlight_sysfs_if, int, 0444);
|
||||||
|
|
||||||
|
#define REPORT_OUTPUT_KEY_EVENTS 0x01
|
||||||
|
#define REPORT_BRIGHTNESS_KEY_EVENTS 0x02
|
||||||
|
static int report_key_events = -1;
|
||||||
|
module_param(report_key_events, int, 0644);
|
||||||
|
MODULE_PARM_DESC(report_key_events,
|
||||||
|
"0: none, 1: output changes, 2: brightness changes, 3: all");
|
||||||
|
|
||||||
static bool device_id_scheme = false;
|
static bool device_id_scheme = false;
|
||||||
module_param(device_id_scheme, bool, 0444);
|
module_param(device_id_scheme, bool, 0444);
|
||||||
|
|
||||||
static bool only_lcd = false;
|
static bool only_lcd = false;
|
||||||
module_param(only_lcd, bool, 0444);
|
module_param(only_lcd, bool, 0444);
|
||||||
|
|
||||||
static int register_count;
|
static DECLARE_COMPLETION(register_done);
|
||||||
static DEFINE_MUTEX(register_count_mutex);
|
static DEFINE_MUTEX(register_done_mutex);
|
||||||
static struct mutex video_list_lock;
|
static struct mutex video_list_lock;
|
||||||
static struct list_head video_bus_head;
|
static struct list_head video_bus_head;
|
||||||
static int acpi_video_bus_add(struct acpi_device *device);
|
static int acpi_video_bus_add(struct acpi_device *device);
|
||||||
|
@ -412,6 +419,13 @@ static int video_enable_only_lcd(const struct dmi_system_id *d)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int video_set_report_key_events(const struct dmi_system_id *id)
|
||||||
|
{
|
||||||
|
if (report_key_events == -1)
|
||||||
|
report_key_events = (uintptr_t)id->driver_data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct dmi_system_id video_dmi_table[] = {
|
static struct dmi_system_id video_dmi_table[] = {
|
||||||
/*
|
/*
|
||||||
* Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
|
* Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
|
||||||
|
@ -500,6 +514,24 @@ static struct dmi_system_id video_dmi_table[] = {
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
* Some machines report wrong key events on the acpi-bus, suppress
|
||||||
|
* key event reporting on these. Note this is only intended to work
|
||||||
|
* around events which are plain wrong. In some cases we get double
|
||||||
|
* events, in this case acpi-video is considered the canonical source
|
||||||
|
* and the events from the other source should be filtered. E.g.
|
||||||
|
* by calling acpi_video_handles_brightness_key_presses() from the
|
||||||
|
* vendor acpi/wmi driver or by using /lib/udev/hwdb.d/60-keyboard.hwdb
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
.callback = video_set_report_key_events,
|
||||||
|
.driver_data = (void *)((uintptr_t)REPORT_OUTPUT_KEY_EVENTS),
|
||||||
|
.ident = "Dell Vostro V131",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1480,7 +1512,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
|
||||||
/* Something vetoed the keypress. */
|
/* Something vetoed the keypress. */
|
||||||
keycode = 0;
|
keycode = 0;
|
||||||
|
|
||||||
if (keycode) {
|
if (keycode && (report_key_events & REPORT_OUTPUT_KEY_EVENTS)) {
|
||||||
input_report_key(input, keycode, 1);
|
input_report_key(input, keycode, 1);
|
||||||
input_sync(input);
|
input_sync(input);
|
||||||
input_report_key(input, keycode, 0);
|
input_report_key(input, keycode, 0);
|
||||||
|
@ -1544,7 +1576,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
|
||||||
|
|
||||||
acpi_notifier_call_chain(device, event, 0);
|
acpi_notifier_call_chain(device, event, 0);
|
||||||
|
|
||||||
if (keycode) {
|
if (keycode && (report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS)) {
|
||||||
input_report_key(input, keycode, 1);
|
input_report_key(input, keycode, 1);
|
||||||
input_sync(input);
|
input_sync(input);
|
||||||
input_report_key(input, keycode, 0);
|
input_report_key(input, keycode, 0);
|
||||||
|
@ -2017,8 +2049,8 @@ int acpi_video_register(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(®ister_count_mutex);
|
mutex_lock(®ister_done_mutex);
|
||||||
if (register_count) {
|
if (completion_done(®ister_done)) {
|
||||||
/*
|
/*
|
||||||
* if the function of acpi_video_register is already called,
|
* if the function of acpi_video_register is already called,
|
||||||
* don't register the acpi_vide_bus again and return no error.
|
* don't register the acpi_vide_bus again and return no error.
|
||||||
|
@ -2039,22 +2071,22 @@ int acpi_video_register(void)
|
||||||
* When the acpi_video_bus is loaded successfully, increase
|
* When the acpi_video_bus is loaded successfully, increase
|
||||||
* the counter reference.
|
* the counter reference.
|
||||||
*/
|
*/
|
||||||
register_count = 1;
|
complete(®ister_done);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
mutex_unlock(®ister_count_mutex);
|
mutex_unlock(®ister_done_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(acpi_video_register);
|
EXPORT_SYMBOL(acpi_video_register);
|
||||||
|
|
||||||
void acpi_video_unregister(void)
|
void acpi_video_unregister(void)
|
||||||
{
|
{
|
||||||
mutex_lock(®ister_count_mutex);
|
mutex_lock(®ister_done_mutex);
|
||||||
if (register_count) {
|
if (completion_done(®ister_done)) {
|
||||||
acpi_bus_unregister_driver(&acpi_video_bus);
|
acpi_bus_unregister_driver(&acpi_video_bus);
|
||||||
register_count = 0;
|
reinit_completion(®ister_done);
|
||||||
}
|
}
|
||||||
mutex_unlock(®ister_count_mutex);
|
mutex_unlock(®ister_done_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(acpi_video_unregister);
|
EXPORT_SYMBOL(acpi_video_unregister);
|
||||||
|
|
||||||
|
@ -2062,16 +2094,30 @@ void acpi_video_unregister_backlight(void)
|
||||||
{
|
{
|
||||||
struct acpi_video_bus *video;
|
struct acpi_video_bus *video;
|
||||||
|
|
||||||
mutex_lock(®ister_count_mutex);
|
mutex_lock(®ister_done_mutex);
|
||||||
if (register_count) {
|
if (completion_done(®ister_done)) {
|
||||||
mutex_lock(&video_list_lock);
|
mutex_lock(&video_list_lock);
|
||||||
list_for_each_entry(video, &video_bus_head, entry)
|
list_for_each_entry(video, &video_bus_head, entry)
|
||||||
acpi_video_bus_unregister_backlight(video);
|
acpi_video_bus_unregister_backlight(video);
|
||||||
mutex_unlock(&video_list_lock);
|
mutex_unlock(&video_list_lock);
|
||||||
}
|
}
|
||||||
mutex_unlock(®ister_count_mutex);
|
mutex_unlock(®ister_done_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool acpi_video_handles_brightness_key_presses(void)
|
||||||
|
{
|
||||||
|
bool have_video_busses;
|
||||||
|
|
||||||
|
wait_for_completion(®ister_done);
|
||||||
|
mutex_lock(&video_list_lock);
|
||||||
|
have_video_busses = !list_empty(&video_bus_head);
|
||||||
|
mutex_unlock(&video_list_lock);
|
||||||
|
|
||||||
|
return have_video_busses &&
|
||||||
|
(report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(acpi_video_handles_brightness_key_presses);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is kind of nasty. Hardware using Intel chipsets may require
|
* This is kind of nasty. Hardware using Intel chipsets may require
|
||||||
* the video opregion code to be run first in order to initialise
|
* the video opregion code to be run first in order to initialise
|
||||||
|
|
|
@ -250,6 +250,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
/* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */
|
||||||
|
.callback = video_detect_force_video,
|
||||||
|
.ident = "SAMSUNG 530U4E/540U4E",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/* Non win8 machines which need native backlight nevertheless */
|
/* Non win8 machines which need native backlight nevertheless */
|
||||||
{
|
{
|
||||||
|
@ -279,6 +288,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = video_detect_force_native,
|
||||||
|
.ident = "Dell Vostro V131",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,6 @@ MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
|
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
|
||||||
|
|
||||||
static int acpi_video;
|
|
||||||
|
|
||||||
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
|
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -159,7 +157,8 @@ static void dell_wmi_process_key(int reported_key)
|
||||||
|
|
||||||
/* Don't report brightness notifications that will also come via ACPI */
|
/* Don't report brightness notifications that will also come via ACPI */
|
||||||
if ((key->keycode == KEY_BRIGHTNESSUP ||
|
if ((key->keycode == KEY_BRIGHTNESSUP ||
|
||||||
key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video)
|
key->keycode == KEY_BRIGHTNESSDOWN) &&
|
||||||
|
acpi_video_handles_brightness_key_presses())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true);
|
sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true);
|
||||||
|
@ -398,7 +397,6 @@ static int __init dell_wmi_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
dmi_walk(find_hk_type, NULL);
|
dmi_walk(find_hk_type, NULL);
|
||||||
acpi_video = acpi_video_get_backlight_type() != acpi_backlight_vendor;
|
|
||||||
|
|
||||||
err = dell_wmi_input_setup();
|
err = dell_wmi_input_setup();
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -3488,7 +3488,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
||||||
/* Do not issue duplicate brightness change events to
|
/* Do not issue duplicate brightness change events to
|
||||||
* userspace. tpacpi_detect_brightness_capabilities() must have
|
* userspace. tpacpi_detect_brightness_capabilities() must have
|
||||||
* been called before this point */
|
* been called before this point */
|
||||||
if (acpi_video_get_backlight_type() != acpi_backlight_vendor) {
|
if (acpi_video_handles_brightness_key_presses()) {
|
||||||
pr_info("This ThinkPad has standard ACPI backlight "
|
pr_info("This ThinkPad has standard ACPI backlight "
|
||||||
"brightness control, supported by the ACPI "
|
"brightness control, supported by the ACPI "
|
||||||
"video driver\n");
|
"video driver\n");
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __ACPI_VIDEO_H
|
#define __ACPI_VIDEO_H
|
||||||
|
|
||||||
#include <linux/errno.h> /* for ENODEV */
|
#include <linux/errno.h> /* for ENODEV */
|
||||||
|
#include <linux/types.h> /* for bool */
|
||||||
|
|
||||||
struct acpi_device;
|
struct acpi_device;
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ extern int acpi_video_get_edid(struct acpi_device *device, int type,
|
||||||
int device_id, void **edid);
|
int device_id, void **edid);
|
||||||
extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
|
extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
|
||||||
extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
|
extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
|
||||||
|
extern bool acpi_video_handles_brightness_key_presses(void);
|
||||||
#else
|
#else
|
||||||
static inline int acpi_video_register(void) { return 0; }
|
static inline int acpi_video_register(void) { return 0; }
|
||||||
static inline void acpi_video_unregister(void) { return; }
|
static inline void acpi_video_unregister(void) { return; }
|
||||||
|
@ -46,6 +48,10 @@ static inline enum acpi_backlight_type acpi_video_get_backlight_type(void)
|
||||||
static inline void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
|
static inline void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
static inline bool acpi_video_handles_brightness_key_presses(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue