You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'platform-drivers-x86-v4.13-1' of git://git.infradead.org/linux-platform-drivers-x86
Pull x86 platform driver updates from Darren Hart: "Introduce new bus architecture for WMI and expose BMOF data through sysfs. Correct several assumptions about WMI instance number from 1 to 0. Further fujitsu-laptop cleanups, continuing to prepare for separation into two modules. Add support for several new ideapad laptops and silead-based tablets. Various minor fixes and const cleanups. Detail summary: sony-laptop: - constify attribute_group and input index array fujitsu-laptop: - rework debugging - do not evaluate ACPI _INI methods - do not update ACPI device power status - sanitize hotkey input device identification - use strcpy to set ACPI device names and classes - remove redundant safety checks - use device-specific data in remaining module code - use device-specific data in LED-related code - explicitly pass ACPI device to call_fext_func() - track the last instantiated FUJ02E3 ACPI device - allocate fujitsu_laptop in acpi_fujitsu_laptop_add() - use device-specific data in backlight code - allocate fujitsu_bl in acpi_fujitsu_bl_add() - distinguish current uses of device-specific data msi-laptop: - constify msipf*_attribute_group eeepc-laptop: - constify platform_attribute_group toshiba_haps: - constify haps_attr_group dell-wmi-led: - Adjust instance of wmi_evaluate_method calls to 0 alienware-wmi: - Adjust instance of wmi_evaluate_method calls to 0 intel_menlow: - Add const to thermal_cooling_device_ops structure acerhdf: - Add const to thermal_cooling_device_ops structure dell-laptop: - Fix bogus keyboard backlight sysfs interface acer-wmi: - Using zero as first WMI instance number - Detect RF Button capability ideapad-laptop: - Add Y720-15IKBN to no_hw_rfkill - Add Y520-15IKBN to no_hw_rfkill - constify rfkill_ops structure - Squelch ACPI event 1 - hide unused 'touchpad_store' - Switch touchpad attribute to be RO - Add sysfs interface for touchpad state silead_dmi: - Add touchscreen info for PoV mobii wintab p800w - Add touchscreen info for Pipo W2S tablet - Add touchscreen info for GP-electronic T701 dell-rbtn: - constify rfkill_ops structures - Improve explanation about DELLABC6 samsung-laptop: - constify rfkill_ops structures panasonic-laptop: - remove unused code samsung-laptop: - Initialize loca variable dell-wmi: - Convert to the WMI bus infrastructure - Add a better description for "stealth mode" - Add a comment explaining the 0xb2 magic number wmi-bmof: - New driver to expose embedded Binary WMI MOF metadata wmi*: - Fix printing info about WDG structure - Add recent copyright statements - Require query for data blocks, rename writable to setable - Add an interface for subdrivers to access sibling devices - Bind the platform device, not the ACPI node - Add a new interface to read block data - Incorporate acpi_install_notify_handler - Instantiate all devices before adding them - Probe data objects for read and write capabilities - Split devices into types and add basic sysfs attributes - Fix error handling when creating devices - Turn WMI into a bus driver - Track wmi devices per ACPI device - Clean up acpi_wmi_add - Pass the acpi_device through to parse_wdg - Drop "Mapper (un)loaded" messages intel_cht_int33fe: - Set supplied-from property on max17047 dev intel_pmc_ipc: - Mark ipc_data_readb() as __maybe_unused topstar-laptop: - Add new device id peaq-wmi: - Add new peaq-wmi driver thinkpad_acpi: - Add a comment about 0 in module_param_call() - Join string literals back toshiba_acpi: - use memdup_user_nul" * tag 'platform-drivers-x86-v4.13-1' of git://git.infradead.org/linux-platform-drivers-x86: (67 commits) platform/x86: sony-laptop: constify attribute_group and input index array platform/x86: fujitsu-laptop: rework debugging platform/x86: fujitsu-laptop: do not evaluate ACPI _INI methods platform/x86: fujitsu-laptop: do not update ACPI device power status platform/x86: fujitsu-laptop: sanitize hotkey input device identification platform/x86: fujitsu-laptop: use strcpy to set ACPI device names and classes platform/x86: fujitsu-laptop: remove redundant safety checks platform/x86: msi-laptop: constify msipf*_attribute_group platform/x86: eeepc-laptop: constify platform_attribute_group platform/x86: toshiba_haps: constify haps_attr_group platform/x86: dell-wmi-led: Adjust instance of wmi_evaluate_method calls to 0 platform/x86: alienware-wmi: Adjust instance of wmi_evaluate_method calls to 0 platform/x86: intel_menlow: Add const to thermal_cooling_device_ops structure platform/x86: acerhdf: Add const to thermal_cooling_device_ops structure platform/x86: dell-laptop: Fix bogus keyboard backlight sysfs interface platform/x86: acer-wmi: Using zero as first WMI instance number platform/x86: ideapad-laptop: Add Y720-15IKBN to no_hw_rfkill platform/x86: ideapad-laptop: Add Y520-15IKBN to no_hw_rfkill platform/x86: silead_dmi: Add touchscreen info for PoV mobii wintab p800w platform/x86: silead_dmi: Add touchscreen info for Pipo W2S tablet ...
This commit is contained in:
@@ -17,3 +17,11 @@ Description:
|
||||
* 2 -> Dust Cleaning
|
||||
* 4 -> Efficient Thermal Dissipation Mode
|
||||
|
||||
What: /sys/devices/platform/ideapad/touchpad
|
||||
Date: May 2017
|
||||
KernelVersion: 4.13
|
||||
Contact: "Ritesh Raj Sarraf <rrs@debian.org>"
|
||||
Description:
|
||||
Control touchpad mode.
|
||||
* 1 -> Switched On
|
||||
* 0 -> Switched Off
|
||||
|
||||
@@ -195,16 +195,6 @@ config FUJITSU_LAPTOP
|
||||
|
||||
If you have a Fujitsu laptop, say Y or M here.
|
||||
|
||||
config FUJITSU_LAPTOP_DEBUG
|
||||
bool "Verbose debug mode for Fujitsu Laptop Extras"
|
||||
depends on FUJITSU_LAPTOP
|
||||
default n
|
||||
---help---
|
||||
Enables extra debug output from the fujitsu extras driver, at the
|
||||
expense of a slight increase in driver size.
|
||||
|
||||
If you are not sure, say N here.
|
||||
|
||||
config FUJITSU_TABLET
|
||||
tristate "Fujitsu Tablet Extras"
|
||||
depends on ACPI
|
||||
@@ -656,6 +646,18 @@ config ACPI_WMI
|
||||
It is safe to enable this driver even if your DSDT doesn't define
|
||||
any ACPI-WMI devices.
|
||||
|
||||
config WMI_BMOF
|
||||
tristate "WMI embedded Binary MOF driver"
|
||||
depends on ACPI_WMI
|
||||
default ACPI_WMI
|
||||
---help---
|
||||
Say Y here if you want to be able to read a firmware-embedded
|
||||
WMI Binary MOF data. Using this requires userspace tools and may be
|
||||
rather tedious.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called wmi-bmof.
|
||||
|
||||
config MSI_WMI
|
||||
tristate "MSI WMI extras"
|
||||
depends on ACPI_WMI
|
||||
@@ -669,6 +671,13 @@ config MSI_WMI
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called msi-wmi.
|
||||
|
||||
config PEAQ_WMI
|
||||
tristate "PEAQ 2-in-1 WMI hotkey driver"
|
||||
depends on ACPI_WMI
|
||||
depends on INPUT
|
||||
help
|
||||
Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
|
||||
|
||||
config TOPSTAR_LAPTOP
|
||||
tristate "Topstar Laptop Extras"
|
||||
depends on ACPI
|
||||
|
||||
@@ -35,8 +35,10 @@ obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o
|
||||
obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
|
||||
obj-$(CONFIG_ACPI_WMI) += wmi.o
|
||||
obj-$(CONFIG_MSI_WMI) += msi-wmi.o
|
||||
obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o
|
||||
obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o
|
||||
obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
|
||||
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
|
||||
|
||||
# toshiba_acpi must link after wmi to ensure that wmi devices are found
|
||||
# before toshiba_acpi initializes
|
||||
|
||||
@@ -149,6 +149,8 @@ struct event_return_value {
|
||||
#define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */
|
||||
#define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */
|
||||
#define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */
|
||||
#define ACER_WMID3_GDS_RFBTN (1<<14) /* RF Button */
|
||||
|
||||
#define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */
|
||||
|
||||
/* Hotkey Customized Setting and Acer Application Status.
|
||||
@@ -221,6 +223,7 @@ struct hotkey_function_type_aa {
|
||||
#define ACER_CAP_BRIGHTNESS (1<<3)
|
||||
#define ACER_CAP_THREEG (1<<4)
|
||||
#define ACER_CAP_ACCEL (1<<5)
|
||||
#define ACER_CAP_RFBTN (1<<6)
|
||||
#define ACER_CAP_ANY (0xFFFFFFFF)
|
||||
|
||||
/*
|
||||
@@ -700,7 +703,7 @@ struct acpi_buffer *result)
|
||||
input.length = sizeof(struct wmab_args);
|
||||
input.pointer = (u8 *)regbuf;
|
||||
|
||||
status = wmi_evaluate_method(AMW0_GUID1, 1, 1, &input, result);
|
||||
status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -965,7 +968,7 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out)
|
||||
u32 tmp = 0;
|
||||
acpi_status status;
|
||||
|
||||
status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result);
|
||||
status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
@@ -1264,6 +1267,10 @@ static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d)
|
||||
interface->capability |= ACER_CAP_THREEG;
|
||||
if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
|
||||
interface->capability |= ACER_CAP_BLUETOOTH;
|
||||
if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) {
|
||||
interface->capability |= ACER_CAP_RFBTN;
|
||||
commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN;
|
||||
}
|
||||
|
||||
commun_fn_key_number = type_aa->commun_fn_key_number;
|
||||
}
|
||||
@@ -1275,7 +1282,7 @@ static acpi_status __init WMID_set_capabilities(void)
|
||||
acpi_status status;
|
||||
u32 devices;
|
||||
|
||||
status = wmi_query_block(WMID_GUID2, 1, &out);
|
||||
status = wmi_query_block(WMID_GUID2, 0, &out);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
@@ -2018,7 +2025,7 @@ static u32 get_wmid_devices(void)
|
||||
acpi_status status;
|
||||
u32 devices = 0;
|
||||
|
||||
status = wmi_query_block(WMID_GUID2, 1, &out);
|
||||
status = wmi_query_block(WMID_GUID2, 0, &out);
|
||||
if (ACPI_FAILURE(status))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -557,7 +557,7 @@ err_out:
|
||||
}
|
||||
|
||||
/* bind fan callbacks to fan device */
|
||||
static struct thermal_cooling_device_ops acerhdf_cooling_ops = {
|
||||
static const struct thermal_cooling_device_ops acerhdf_cooling_ops = {
|
||||
.get_max_state = acerhdf_get_max_state,
|
||||
.get_cur_state = acerhdf_get_cur_state,
|
||||
.set_cur_state = acerhdf_set_cur_state,
|
||||
|
||||
@@ -303,7 +303,7 @@ static int alienware_update_led(struct platform_zone *zone)
|
||||
}
|
||||
pr_debug("alienware-wmi: guid %s method %d\n", guid, method_id);
|
||||
|
||||
status = wmi_evaluate_method(guid, 1, method_id, &input, NULL);
|
||||
status = wmi_evaluate_method(guid, 0, method_id, &input, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_err("alienware-wmi: zone set failure: %u\n", status);
|
||||
return ACPI_FAILURE(status);
|
||||
@@ -352,7 +352,7 @@ static int wmax_brightness(int brightness)
|
||||
};
|
||||
input.length = (acpi_size) sizeof(args);
|
||||
input.pointer = &args;
|
||||
status = wmi_evaluate_method(WMAX_CONTROL_GUID, 1,
|
||||
status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
|
||||
WMAX_METHOD_BRIGHTNESS, &input, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_err("alienware-wmi: brightness set failure: %u\n", status);
|
||||
@@ -506,10 +506,10 @@ static acpi_status alienware_wmax_command(struct wmax_basic_args *in_args,
|
||||
if (out_data != NULL) {
|
||||
output.length = ACPI_ALLOCATE_BUFFER;
|
||||
output.pointer = NULL;
|
||||
status = wmi_evaluate_method(WMAX_CONTROL_GUID, 1,
|
||||
status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
|
||||
command, &input, &output);
|
||||
} else
|
||||
status = wmi_evaluate_method(WMAX_CONTROL_GUID, 1,
|
||||
status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
|
||||
command, &input, NULL);
|
||||
|
||||
if (ACPI_SUCCESS(status) && out_data != NULL) {
|
||||
|
||||
@@ -1510,7 +1510,11 @@ static void kbd_init(void)
|
||||
ret = kbd_init_info();
|
||||
kbd_init_tokens();
|
||||
|
||||
if (kbd_token_bits != 0 || ret == 0)
|
||||
/*
|
||||
* Only supports keyboard backlight when it has at least two modes.
|
||||
*/
|
||||
if ((ret == 0 && (kbd_info.levels != 0 || kbd_mode_levels_count >= 2))
|
||||
|| kbd_get_valid_token_counts() >= 2)
|
||||
kbd_led_present = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ static int rbtn_rfkill_set_block(void *data, bool blocked)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct rfkill_ops rbtn_ops = {
|
||||
static const struct rfkill_ops rbtn_ops = {
|
||||
.query = rbtn_rfkill_query,
|
||||
.set_block = rbtn_rfkill_set_block,
|
||||
};
|
||||
@@ -221,16 +221,27 @@ static const struct acpi_device_id rbtn_ids[] = {
|
||||
|
||||
/*
|
||||
* This driver can also handle the "DELLABC6" device that
|
||||
* appears on the XPS 13 9350, but that device is disabled
|
||||
* by the DSDT unless booted with acpi_osi="!Windows 2012"
|
||||
* acpi_osi="!Windows 2013". Even if we boot that and bind
|
||||
* the driver, we seem to have inconsistent behavior in
|
||||
* which NetworkManager can get out of sync with the rfkill
|
||||
* state.
|
||||
* appears on the XPS 13 9350, but that device is disabled by
|
||||
* the DSDT unless booted with acpi_osi="!Windows 2012"
|
||||
* acpi_osi="!Windows 2013".
|
||||
*
|
||||
* On the XPS 13 9350 and similar laptops, we're not supposed to
|
||||
* use DELLABC6 at all. Instead, we handle the rfkill button
|
||||
* via the intel-hid driver.
|
||||
* According to Mario at Dell:
|
||||
*
|
||||
* DELLABC6 is a custom interface that was created solely to
|
||||
* have airplane mode support for Windows 7. For Windows 10
|
||||
* the proper interface is to use that which is handled by
|
||||
* intel-hid. A OEM airplane mode driver is not used.
|
||||
*
|
||||
* Since the kernel doesn't identify as Windows 7 it would be
|
||||
* incorrect to do attempt to use that interface.
|
||||
*
|
||||
* Even if we override _OSI and bind to DELLABC6, we end up with
|
||||
* inconsistent behavior in which userspace can get out of sync
|
||||
* with the rfkill state as it conflicts with events from
|
||||
* intel-hid.
|
||||
*
|
||||
* The upshot is that it is better to just ignore DELLABC6
|
||||
* devices.
|
||||
*/
|
||||
|
||||
{ "", 0 },
|
||||
|
||||
@@ -68,7 +68,7 @@ static int dell_led_perform_fn(u8 length, u8 result_code, u8 device_id,
|
||||
input.length = sizeof(struct bios_args);
|
||||
input.pointer = &args;
|
||||
|
||||
status = wmi_evaluate_method(DELL_LED_BIOS_GUID, 1, 1, &input, &output);
|
||||
status = wmi_evaluate_method(DELL_LED_BIOS_GUID, 0, 1, &input, &output);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/wmi.h>
|
||||
#include <acpi/video.h>
|
||||
#include "dell-smbios.h"
|
||||
|
||||
@@ -53,6 +54,10 @@ static bool wmi_requires_smbios_request;
|
||||
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
|
||||
MODULE_ALIAS("wmi:"DELL_DESCRIPTOR_GUID);
|
||||
|
||||
struct dell_wmi_priv {
|
||||
struct input_dev *input_dev;
|
||||
};
|
||||
|
||||
static int __init dmi_matched(const struct dmi_system_id *dmi)
|
||||
{
|
||||
wmi_requires_smbios_request = 1;
|
||||
@@ -86,7 +91,7 @@ static const struct dmi_system_id dell_wmi_smbios_list[] __initconst = {
|
||||
* notifications (rather than requests for change) or are also sent
|
||||
* via the keyboard controller so should not be sent again.
|
||||
*/
|
||||
static const struct key_entry dell_wmi_keymap_type_0000[] __initconst = {
|
||||
static const struct key_entry dell_wmi_keymap_type_0000[] = {
|
||||
{ KE_IGNORE, 0x003a, { KEY_CAPSLOCK } },
|
||||
|
||||
/* Key code is followed by brightness level */
|
||||
@@ -207,7 +212,7 @@ struct dell_dmi_results {
|
||||
};
|
||||
|
||||
/* Uninitialized entries here are KEY_RESERVED == 0. */
|
||||
static const u16 bios_to_linux_keycode[256] __initconst = {
|
||||
static const u16 bios_to_linux_keycode[256] = {
|
||||
[0] = KEY_MEDIA,
|
||||
[1] = KEY_NEXTSONG,
|
||||
[2] = KEY_PLAYPAUSE,
|
||||
@@ -256,7 +261,7 @@ static const u16 bios_to_linux_keycode[256] __initconst = {
|
||||
* These are applied if the 0xB2 DMI hotkey table is present and doesn't
|
||||
* override them.
|
||||
*/
|
||||
static const struct key_entry dell_wmi_keymap_type_0010[] __initconst = {
|
||||
static const struct key_entry dell_wmi_keymap_type_0010[] = {
|
||||
/* Fn-lock */
|
||||
{ KE_IGNORE, 0x151, { KEY_RESERVED } },
|
||||
|
||||
@@ -272,7 +277,12 @@ static const struct key_entry dell_wmi_keymap_type_0010[] __initconst = {
|
||||
/* RGB keyboard backlight control */
|
||||
{ KE_IGNORE, 0x154, { KEY_RESERVED } },
|
||||
|
||||
/* Stealth mode toggle */
|
||||
/*
|
||||
* Stealth mode toggle. This will "disable all lights and sounds".
|
||||
* The action is performed by the BIOS and EC; the WMI event is just
|
||||
* a notification. On the XPS 13 9350, this is Fn+F7, and there's
|
||||
* a BIOS setting to enable and disable the hotkey.
|
||||
*/
|
||||
{ KE_IGNORE, 0x155, { KEY_RESERVED } },
|
||||
|
||||
/* Rugged magnetic dock attach/detach events */
|
||||
@@ -289,7 +299,7 @@ static const struct key_entry dell_wmi_keymap_type_0010[] __initconst = {
|
||||
/*
|
||||
* Keymap for WMI events of type 0x0011
|
||||
*/
|
||||
static const struct key_entry dell_wmi_keymap_type_0011[] __initconst = {
|
||||
static const struct key_entry dell_wmi_keymap_type_0011[] = {
|
||||
/* Battery unplugged */
|
||||
{ KE_IGNORE, 0xfff0, { KEY_RESERVED } },
|
||||
|
||||
@@ -304,13 +314,12 @@ static const struct key_entry dell_wmi_keymap_type_0011[] __initconst = {
|
||||
{ KE_IGNORE, 0x02f6, { KEY_RESERVED } },
|
||||
};
|
||||
|
||||
static struct input_dev *dell_wmi_input_dev;
|
||||
|
||||
static void dell_wmi_process_key(int type, int code)
|
||||
static void dell_wmi_process_key(struct wmi_device *wdev, int type, int code)
|
||||
{
|
||||
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
|
||||
const struct key_entry *key;
|
||||
|
||||
key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
|
||||
key = sparse_keymap_entry_from_scancode(priv->input_dev,
|
||||
(type << 16) | code);
|
||||
if (!key) {
|
||||
pr_info("Unknown key with type 0x%04x and code 0x%04x pressed\n",
|
||||
@@ -333,33 +342,18 @@ static void dell_wmi_process_key(int type, int code)
|
||||
dell_laptop_call_notifier(
|
||||
DELL_LAPTOP_KBD_BACKLIGHT_BRIGHTNESS_CHANGED, NULL);
|
||||
|
||||
sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true);
|
||||
sparse_keymap_report_entry(priv->input_dev, key, 1, true);
|
||||
}
|
||||
|
||||
static void dell_wmi_notify(u32 value, void *context)
|
||||
static void dell_wmi_notify(struct wmi_device *wdev,
|
||||
union acpi_object *obj)
|
||||
{
|
||||
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
acpi_size buffer_size;
|
||||
u16 *buffer_entry, *buffer_end;
|
||||
acpi_size buffer_size;
|
||||
int len, i;
|
||||
|
||||
status = wmi_get_event_data(value, &response);
|
||||
if (status != AE_OK) {
|
||||
pr_warn("bad event status 0x%x\n", status);
|
||||
return;
|
||||
}
|
||||
|
||||
obj = (union acpi_object *)response.pointer;
|
||||
if (!obj) {
|
||||
pr_warn("no response\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj->type != ACPI_TYPE_BUFFER) {
|
||||
pr_warn("bad response type %x\n", obj->type);
|
||||
kfree(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -404,13 +398,14 @@ static void dell_wmi_notify(u32 value, void *context)
|
||||
switch (buffer_entry[1]) {
|
||||
case 0x0000: /* One key pressed or event occurred */
|
||||
if (len > 2)
|
||||
dell_wmi_process_key(0x0000, buffer_entry[2]);
|
||||
dell_wmi_process_key(wdev, 0x0000,
|
||||
buffer_entry[2]);
|
||||
/* Other entries could contain additional information */
|
||||
break;
|
||||
case 0x0010: /* Sequence of keys pressed */
|
||||
case 0x0011: /* Sequence of events occurred */
|
||||
for (i = 2; i < len; ++i)
|
||||
dell_wmi_process_key(buffer_entry[1],
|
||||
dell_wmi_process_key(wdev, buffer_entry[1],
|
||||
buffer_entry[i]);
|
||||
break;
|
||||
default: /* Unknown event */
|
||||
@@ -423,7 +418,6 @@ static void dell_wmi_notify(u32 value, void *context)
|
||||
|
||||
}
|
||||
|
||||
kfree(obj);
|
||||
}
|
||||
|
||||
static bool have_scancode(u32 scancode, const struct key_entry *keymap, int len)
|
||||
@@ -437,9 +431,7 @@ static bool have_scancode(u32 scancode, const struct key_entry *keymap, int len)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void __init handle_dmi_entry(const struct dmi_header *dm,
|
||||
void *opaque)
|
||||
|
||||
static void handle_dmi_entry(const struct dmi_header *dm, void *opaque)
|
||||
{
|
||||
struct dell_dmi_results *results = opaque;
|
||||
struct dell_bios_hotkey_table *table;
|
||||
@@ -449,6 +441,7 @@ static void __init handle_dmi_entry(const struct dmi_header *dm,
|
||||
if (results->err || results->keymap)
|
||||
return; /* We already found the hotkey table. */
|
||||
|
||||
/* The Dell hotkey table is type 0xB2. Scan until we find it. */
|
||||
if (dm->type != 0xb2)
|
||||
return;
|
||||
|
||||
@@ -509,19 +502,20 @@ static void __init handle_dmi_entry(const struct dmi_header *dm,
|
||||
results->keymap_size = pos;
|
||||
}
|
||||
|
||||
static int __init dell_wmi_input_setup(void)
|
||||
static int dell_wmi_input_setup(struct wmi_device *wdev)
|
||||
{
|
||||
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
|
||||
struct dell_dmi_results dmi_results = {};
|
||||
struct key_entry *keymap;
|
||||
int err, i, pos = 0;
|
||||
|
||||
dell_wmi_input_dev = input_allocate_device();
|
||||
if (!dell_wmi_input_dev)
|
||||
priv->input_dev = input_allocate_device();
|
||||
if (!priv->input_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
dell_wmi_input_dev->name = "Dell WMI hotkeys";
|
||||
dell_wmi_input_dev->phys = "wmi/input0";
|
||||
dell_wmi_input_dev->id.bustype = BUS_HOST;
|
||||
priv->input_dev->name = "Dell WMI hotkeys";
|
||||
priv->input_dev->id.bustype = BUS_HOST;
|
||||
priv->input_dev->dev.parent = &wdev->dev;
|
||||
|
||||
if (dmi_walk(handle_dmi_entry, &dmi_results)) {
|
||||
/*
|
||||
@@ -596,7 +590,7 @@ static int __init dell_wmi_input_setup(void)
|
||||
|
||||
keymap[pos].type = KE_END;
|
||||
|
||||
err = sparse_keymap_setup(dell_wmi_input_dev, keymap, NULL);
|
||||
err = sparse_keymap_setup(priv->input_dev, keymap, NULL);
|
||||
/*
|
||||
* Sparse keymap library makes a copy of keymap so we don't need the
|
||||
* original one that was allocated.
|
||||
@@ -605,17 +599,24 @@ static int __init dell_wmi_input_setup(void)
|
||||
if (err)
|
||||
goto err_free_dev;
|
||||
|
||||
err = input_register_device(dell_wmi_input_dev);
|
||||
err = input_register_device(priv->input_dev);
|
||||
if (err)
|
||||
goto err_free_dev;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_dev:
|
||||
input_free_device(dell_wmi_input_dev);
|
||||
input_free_device(priv->input_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void dell_wmi_input_destroy(struct wmi_device *wdev)
|
||||
{
|
||||
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
|
||||
|
||||
input_unregister_device(priv->input_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Descriptor buffer is 128 byte long and contains:
|
||||
*
|
||||
@@ -714,46 +715,55 @@ static int dell_wmi_events_set_enabled(bool enable)
|
||||
return dell_smbios_error(ret);
|
||||
}
|
||||
|
||||
static int dell_wmi_probe(struct wmi_device *wdev)
|
||||
{
|
||||
struct dell_wmi_priv *priv = devm_kzalloc(
|
||||
&wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);
|
||||
|
||||
dev_set_drvdata(&wdev->dev, priv);
|
||||
|
||||
return dell_wmi_input_setup(wdev);
|
||||
}
|
||||
|
||||
static int dell_wmi_remove(struct wmi_device *wdev)
|
||||
{
|
||||
dell_wmi_input_destroy(wdev);
|
||||
return 0;
|
||||
}
|
||||
static const struct wmi_device_id dell_wmi_id_table[] = {
|
||||
{ .guid_string = DELL_EVENT_GUID },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct wmi_driver dell_wmi_driver = {
|
||||
.driver = {
|
||||
.name = "dell-wmi",
|
||||
},
|
||||
.id_table = dell_wmi_id_table,
|
||||
.probe = dell_wmi_probe,
|
||||
.remove = dell_wmi_remove,
|
||||
.notify = dell_wmi_notify,
|
||||
};
|
||||
|
||||
static int __init dell_wmi_init(void)
|
||||
{
|
||||
int err;
|
||||
acpi_status status;
|
||||
|
||||
if (!wmi_has_guid(DELL_EVENT_GUID) ||
|
||||
!wmi_has_guid(DELL_DESCRIPTOR_GUID)) {
|
||||
pr_warn("Dell WMI GUID were not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = dell_wmi_check_descriptor_buffer();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = dell_wmi_input_setup();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
status = wmi_install_notify_handler(DELL_EVENT_GUID,
|
||||
dell_wmi_notify, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
input_unregister_device(dell_wmi_input_dev);
|
||||
pr_err("Unable to register notify handler - %d\n", status);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dmi_check_system(dell_wmi_smbios_list);
|
||||
|
||||
if (wmi_requires_smbios_request) {
|
||||
err = dell_wmi_events_set_enabled(true);
|
||||
if (err) {
|
||||
pr_err("Failed to enable WMI events\n");
|
||||
wmi_remove_notify_handler(DELL_EVENT_GUID);
|
||||
input_unregister_device(dell_wmi_input_dev);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return wmi_driver_register(&dell_wmi_driver);
|
||||
}
|
||||
module_init(dell_wmi_init);
|
||||
|
||||
@@ -761,7 +771,7 @@ static void __exit dell_wmi_exit(void)
|
||||
{
|
||||
if (wmi_requires_smbios_request)
|
||||
dell_wmi_events_set_enabled(false);
|
||||
wmi_remove_notify_handler(DELL_EVENT_GUID);
|
||||
input_unregister_device(dell_wmi_input_dev);
|
||||
|
||||
wmi_driver_unregister(&dell_wmi_driver);
|
||||
}
|
||||
module_exit(dell_wmi_exit);
|
||||
|
||||
@@ -445,7 +445,7 @@ static struct attribute *platform_attributes[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group platform_attribute_group = {
|
||||
static const struct attribute_group platform_attribute_group = {
|
||||
.attrs = platform_attributes
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -423,9 +423,43 @@ static ssize_t store_ideapad_fan(struct device *dev,
|
||||
|
||||
static DEVICE_ATTR(fan_mode, 0644, show_ideapad_fan, store_ideapad_fan);
|
||||
|
||||
static ssize_t touchpad_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct ideapad_private *priv = dev_get_drvdata(dev);
|
||||
unsigned long result;
|
||||
|
||||
if (read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &result))
|
||||
return sprintf(buf, "-1\n");
|
||||
return sprintf(buf, "%lu\n", result);
|
||||
}
|
||||
|
||||
/* Switch to RO for now: It might be revisited in the future */
|
||||
static ssize_t __maybe_unused touchpad_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct ideapad_private *priv = dev_get_drvdata(dev);
|
||||
bool state;
|
||||
int ret;
|
||||
|
||||
ret = kstrtobool(buf, &state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, state);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(touchpad);
|
||||
|
||||
static struct attribute *ideapad_attributes[] = {
|
||||
&dev_attr_camera_power.attr,
|
||||
&dev_attr_fan_mode.attr,
|
||||
&dev_attr_touchpad.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -478,7 +512,7 @@ static int ideapad_rfk_set(void *data, bool blocked)
|
||||
return write_ec_cmd(priv->priv->adev->handle, opcode, !blocked);
|
||||
}
|
||||
|
||||
static struct rfkill_ops ideapad_rfk_ops = {
|
||||
static const struct rfkill_ops ideapad_rfk_ops = {
|
||||
.set_block = ideapad_rfk_set,
|
||||
};
|
||||
|
||||
@@ -810,7 +844,6 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
|
||||
case 8:
|
||||
case 7:
|
||||
case 6:
|
||||
case 1:
|
||||
ideapad_input_report(priv, vpc_bit);
|
||||
break;
|
||||
case 5:
|
||||
@@ -828,6 +861,13 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
|
||||
case 0:
|
||||
ideapad_check_special_buttons(priv);
|
||||
break;
|
||||
case 1:
|
||||
/* Some IdeaPads report event 1 every ~20
|
||||
* seconds while on battery power; some
|
||||
* report this when changing to/from tablet
|
||||
* mode. Squelch this event.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
pr_info("Unknown event: %lu\n", vpc_bit);
|
||||
}
|
||||
@@ -910,6 +950,20 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-17ISK"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Lenovo Legion Y520-15IKBN",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKBN"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Lenovo Legion Y720-15IKBN",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y720-15IKBN"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Lenovo Yoga 2 11 / 13 / Pro",
|
||||
.matches = {
|
||||
|
||||
@@ -34,6 +34,13 @@ struct cht_int33fe_data {
|
||||
struct i2c_client *pi3usb30532;
|
||||
};
|
||||
|
||||
static const char * const max17047_suppliers[] = { "bq24190-charger" };
|
||||
|
||||
static const struct property_entry max17047_props[] = {
|
||||
PROPERTY_ENTRY_STRING_ARRAY("supplied-from", max17047_suppliers),
|
||||
{ }
|
||||
};
|
||||
|
||||
static int cht_int33fe_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
@@ -70,6 +77,7 @@ static int cht_int33fe_probe(struct i2c_client *client)
|
||||
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strlcpy(board_info.type, "max17047", I2C_NAME_SIZE);
|
||||
board_info.properties = max17047_props;
|
||||
|
||||
data->max17047 = i2c_acpi_new_device(dev, 1, &board_info);
|
||||
if (!data->max17047)
|
||||
|
||||
@@ -142,7 +142,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops memory_cooling_ops = {
|
||||
static const struct thermal_cooling_device_ops memory_cooling_ops = {
|
||||
.get_max_state = memory_get_max_bandwidth,
|
||||
.get_cur_state = memory_get_cur_bandwidth,
|
||||
.set_cur_state = memory_set_cur_bandwidth,
|
||||
|
||||
@@ -186,7 +186,7 @@ static inline void ipc_data_writel(u32 data, u32 offset)
|
||||
writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
|
||||
}
|
||||
|
||||
static inline u8 ipc_data_readb(u32 offset)
|
||||
static inline u8 __maybe_unused ipc_data_readb(u32 offset)
|
||||
{
|
||||
return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
|
||||
}
|
||||
|
||||
@@ -563,11 +563,11 @@ static struct attribute *msipf_old_attributes[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group msipf_attribute_group = {
|
||||
static const struct attribute_group msipf_attribute_group = {
|
||||
.attrs = msipf_attributes
|
||||
};
|
||||
|
||||
static struct attribute_group msipf_old_attribute_group = {
|
||||
static const struct attribute_group msipf_old_attribute_group = {
|
||||
.attrs = msipf_old_attributes
|
||||
};
|
||||
|
||||
|
||||
@@ -228,10 +228,6 @@ struct pcc_acpi {
|
||||
struct backlight_device *backlight;
|
||||
};
|
||||
|
||||
struct pcc_keyinput {
|
||||
struct acpi_hotkey *hotkey;
|
||||
};
|
||||
|
||||
/* method access functions */
|
||||
static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* PEAQ 2-in-1 WMI hotkey driver
|
||||
* Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/input-polldev.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define PEAQ_DOLBY_BUTTON_GUID "ABBC0F6F-8EA1-11D1-00A0-C90629100000"
|
||||
#define PEAQ_DOLBY_BUTTON_METHOD_ID 5
|
||||
#define PEAQ_POLL_INTERVAL_MS 250
|
||||
#define PEAQ_POLL_IGNORE_MS 500
|
||||
#define PEAQ_POLL_MAX_MS 1000
|
||||
|
||||
MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
|
||||
|
||||
static unsigned int peaq_ignore_events_counter;
|
||||
static struct input_polled_dev *peaq_poll_dev;
|
||||
|
||||
/*
|
||||
* The Dolby button (yes really a Dolby button) causes an ACPI variable to get
|
||||
* set on both press and release. The WMI method checks and clears that flag.
|
||||
* So for a press + release we will get back One from the WMI method either once
|
||||
* (if polling after the release) or twice (polling between press and release).
|
||||
* We ignore events for 0.5s after the first event to avoid reporting 2 presses.
|
||||
*/
|
||||
static void peaq_wmi_poll(struct input_polled_dev *dev)
|
||||
{
|
||||
union acpi_object obj;
|
||||
acpi_status status;
|
||||
u32 dummy = 0;
|
||||
|
||||
struct acpi_buffer input = { sizeof(dummy), &dummy };
|
||||
struct acpi_buffer output = { sizeof(obj), &obj };
|
||||
|
||||
status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1,
|
||||
PEAQ_DOLBY_BUTTON_METHOD_ID,
|
||||
&input, &output);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
if (obj.type != ACPI_TYPE_INTEGER) {
|
||||
dev_err(&peaq_poll_dev->input->dev,
|
||||
"Error WMBC did not return an integer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (peaq_ignore_events_counter && --peaq_ignore_events_counter > 0)
|
||||
return;
|
||||
|
||||
if (obj.integer.value) {
|
||||
input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 1);
|
||||
input_sync(peaq_poll_dev->input);
|
||||
input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
|
||||
input_sync(peaq_poll_dev->input);
|
||||
peaq_ignore_events_counter = max(1u,
|
||||
PEAQ_POLL_IGNORE_MS / peaq_poll_dev->poll_interval);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init peaq_wmi_init(void)
|
||||
{
|
||||
if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
|
||||
return -ENODEV;
|
||||
|
||||
peaq_poll_dev = input_allocate_polled_device();
|
||||
if (!peaq_poll_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
peaq_poll_dev->poll = peaq_wmi_poll;
|
||||
peaq_poll_dev->poll_interval = PEAQ_POLL_INTERVAL_MS;
|
||||
peaq_poll_dev->poll_interval_max = PEAQ_POLL_MAX_MS;
|
||||
peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
|
||||
peaq_poll_dev->input->phys = "wmi/input0";
|
||||
peaq_poll_dev->input->id.bustype = BUS_HOST;
|
||||
input_set_capability(peaq_poll_dev->input, EV_KEY, KEY_SOUND);
|
||||
|
||||
return input_register_polled_device(peaq_poll_dev);
|
||||
}
|
||||
|
||||
static void __exit peaq_wmi_exit(void)
|
||||
{
|
||||
if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
|
||||
return;
|
||||
|
||||
input_unregister_polled_device(peaq_poll_dev);
|
||||
}
|
||||
|
||||
module_init(peaq_wmi_init);
|
||||
module_exit(peaq_wmi_exit);
|
||||
|
||||
MODULE_DESCRIPTION("PEAQ 2-in-1 WMI hotkey driver");
|
||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -591,7 +591,7 @@ static int seclinux_rfkill_set(void *data, bool blocked)
|
||||
!blocked);
|
||||
}
|
||||
|
||||
static struct rfkill_ops seclinux_rfkill_ops = {
|
||||
static const struct rfkill_ops seclinux_rfkill_ops = {
|
||||
.set_block = seclinux_rfkill_set,
|
||||
};
|
||||
|
||||
@@ -651,7 +651,7 @@ static void swsmi_rfkill_query(struct rfkill *rfkill, void *priv)
|
||||
rfkill_set_sw_state(rfkill, !ret);
|
||||
}
|
||||
|
||||
static struct rfkill_ops swsmi_rfkill_ops = {
|
||||
static const struct rfkill_ops swsmi_rfkill_ops = {
|
||||
.set_block = swsmi_rfkill_set,
|
||||
.query = swsmi_rfkill_query,
|
||||
};
|
||||
@@ -1446,9 +1446,9 @@ static int __init samsung_sabi_init(struct samsung_laptop *samsung)
|
||||
const struct sabi_config *config = NULL;
|
||||
const struct sabi_commands *commands;
|
||||
unsigned int ifaceP;
|
||||
int loca = 0xffff;
|
||||
int ret = 0;
|
||||
int i;
|
||||
int loca;
|
||||
|
||||
samsung->f0000_segment = ioremap_nocache(0xf0000, 0xffff);
|
||||
if (!samsung->f0000_segment) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user