mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 21:53:44 +00:00
platform-drivers-x86 for v6.7-3
Highlights: - asus-wmi: Solve i8042 filter resource handling, input, and suspend issues - wmi: Skip zero instance WMI blocks to avoid issues with some laptops - mlxbf-bootctl: Differentiate dev/production keys - platform/surface: Correct serdev related return value to avoid leaking errno into userspace - Error checking fixes The following is an automated shortlog grouped by driver: asus-wmi: - Change q500a_i8042_filter() into a generic i8042-filter - disable USB0 hub on ROG Ally before suspend - Filter Volume key presses if also reported via atkbd - Move i8042 filter install to shared asus-wmi code mellanox: - Add null pointer checks for devm_kasprintf() - Check devm_hwmon_device_register_with_groups() return value mlxbf-bootctl: - correctly identify secure boot with development keys surface: aggregator: - fix recv_buf() return value wmi: - Skip blocks with zero instances -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQSCSUwRdwTNL2MhaBlZrE9hU+XOMQUCZXC60QAKCRBZrE9hU+XO McbwAPwIlGYIdYzUXGVGCrCBq7wtBR8ADfFqIa42hUlkDyZ4tAEA8LgrZutAFwhq 35kVk6FSwrUGuIhX5TkxTxnp814nzwE= =iiB1 -----END PGP SIGNATURE----- Merge tag 'platform-drivers-x86-v6.7-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86 Pull x86 platform driver fixes from Ilpo Järvinen: - Fix i8042 filter resource handling, input, and suspend issues in asus-wmi - Skip zero instance WMI blocks to avoid issues with some laptops - Differentiate dev/production keys in mlxbf-bootctl - Correct surface serdev related return value to avoid leaking errno into userspace - Error checking fixes * tag 'platform-drivers-x86-v6.7-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: platform/mellanox: Check devm_hwmon_device_register_with_groups() return value platform/mellanox: Add null pointer checks for devm_kasprintf() mlxbf-bootctl: correctly identify secure boot with development keys platform/x86: wmi: Skip blocks with zero instances platform/surface: aggregator: fix recv_buf() return value platform/x86: asus-wmi: disable USB0 hub on ROG Ally before suspend platform/x86: asus-wmi: Filter Volume key presses if also reported via atkbd platform/x86: asus-wmi: Change q500a_i8042_filter() into a generic i8042-filter platform/x86: asus-wmi: Move i8042 filter install to shared asus-wmi code
This commit is contained in:
commit
33d42bde99
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#define MLXBF_BOOTCTL_SB_SECURE_MASK 0x03
|
#define MLXBF_BOOTCTL_SB_SECURE_MASK 0x03
|
||||||
#define MLXBF_BOOTCTL_SB_TEST_MASK 0x0c
|
#define MLXBF_BOOTCTL_SB_TEST_MASK 0x0c
|
||||||
|
#define MLXBF_BOOTCTL_SB_DEV_MASK BIT(4)
|
||||||
|
|
||||||
#define MLXBF_SB_KEY_NUM 4
|
#define MLXBF_SB_KEY_NUM 4
|
||||||
|
|
||||||
@ -40,11 +41,18 @@ static struct mlxbf_bootctl_name boot_names[] = {
|
|||||||
{ MLXBF_BOOTCTL_NONE, "none" },
|
{ MLXBF_BOOTCTL_NONE, "none" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION = 0,
|
||||||
|
MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE = 1,
|
||||||
|
MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE = 2,
|
||||||
|
MLXBF_BOOTCTL_SB_LIFECYCLE_RMA = 3
|
||||||
|
};
|
||||||
|
|
||||||
static const char * const mlxbf_bootctl_lifecycle_states[] = {
|
static const char * const mlxbf_bootctl_lifecycle_states[] = {
|
||||||
[0] = "Production",
|
[MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION] = "Production",
|
||||||
[1] = "GA Secured",
|
[MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE] = "GA Secured",
|
||||||
[2] = "GA Non-Secured",
|
[MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE] = "GA Non-Secured",
|
||||||
[3] = "RMA",
|
[MLXBF_BOOTCTL_SB_LIFECYCLE_RMA] = "RMA",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Log header format. */
|
/* Log header format. */
|
||||||
@ -247,25 +255,30 @@ static ssize_t second_reset_action_store(struct device *dev,
|
|||||||
static ssize_t lifecycle_state_show(struct device *dev,
|
static ssize_t lifecycle_state_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
|
int status_bits;
|
||||||
|
int use_dev_key;
|
||||||
|
int test_state;
|
||||||
int lc_state;
|
int lc_state;
|
||||||
|
|
||||||
lc_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
|
status_bits = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
|
||||||
MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE);
|
MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE);
|
||||||
if (lc_state < 0)
|
if (status_bits < 0)
|
||||||
return lc_state;
|
return status_bits;
|
||||||
|
|
||||||
lc_state &=
|
use_dev_key = status_bits & MLXBF_BOOTCTL_SB_DEV_MASK;
|
||||||
MLXBF_BOOTCTL_SB_TEST_MASK | MLXBF_BOOTCTL_SB_SECURE_MASK;
|
test_state = status_bits & MLXBF_BOOTCTL_SB_TEST_MASK;
|
||||||
|
lc_state = status_bits & MLXBF_BOOTCTL_SB_SECURE_MASK;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the test bits are set, we specify that the current state may be
|
* If the test bits are set, we specify that the current state may be
|
||||||
* due to using the test bits.
|
* due to using the test bits.
|
||||||
*/
|
*/
|
||||||
if (lc_state & MLXBF_BOOTCTL_SB_TEST_MASK) {
|
if (test_state) {
|
||||||
lc_state &= MLXBF_BOOTCTL_SB_SECURE_MASK;
|
|
||||||
|
|
||||||
return sprintf(buf, "%s(test)\n",
|
return sprintf(buf, "%s(test)\n",
|
||||||
mlxbf_bootctl_lifecycle_states[lc_state]);
|
mlxbf_bootctl_lifecycle_states[lc_state]);
|
||||||
|
} else if (use_dev_key &&
|
||||||
|
(lc_state == MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE)) {
|
||||||
|
return sprintf(buf, "Secured (development)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]);
|
return sprintf(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]);
|
||||||
|
@ -1771,6 +1771,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
|
|||||||
attr->dev_attr.show = mlxbf_pmc_event_list_show;
|
attr->dev_attr.show = mlxbf_pmc_event_list_show;
|
||||||
attr->nr = blk_num;
|
attr->nr = blk_num;
|
||||||
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "event_list");
|
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "event_list");
|
||||||
|
if (!attr->dev_attr.attr.name)
|
||||||
|
return -ENOMEM;
|
||||||
pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;
|
pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;
|
||||||
attr = NULL;
|
attr = NULL;
|
||||||
|
|
||||||
@ -1784,6 +1786,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
|
|||||||
attr->nr = blk_num;
|
attr->nr = blk_num;
|
||||||
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||||
"enable");
|
"enable");
|
||||||
|
if (!attr->dev_attr.attr.name)
|
||||||
|
return -ENOMEM;
|
||||||
pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
|
pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
|
||||||
attr = NULL;
|
attr = NULL;
|
||||||
}
|
}
|
||||||
@ -1810,6 +1814,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
|
|||||||
attr->nr = blk_num;
|
attr->nr = blk_num;
|
||||||
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||||
"counter%d", j);
|
"counter%d", j);
|
||||||
|
if (!attr->dev_attr.attr.name)
|
||||||
|
return -ENOMEM;
|
||||||
pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
|
pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
|
||||||
attr = NULL;
|
attr = NULL;
|
||||||
|
|
||||||
@ -1821,6 +1827,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
|
|||||||
attr->nr = blk_num;
|
attr->nr = blk_num;
|
||||||
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||||
"event%d", j);
|
"event%d", j);
|
||||||
|
if (!attr->dev_attr.attr.name)
|
||||||
|
return -ENOMEM;
|
||||||
pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
|
pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
|
||||||
attr = NULL;
|
attr = NULL;
|
||||||
}
|
}
|
||||||
@ -1853,6 +1861,8 @@ static int mlxbf_pmc_init_perftype_reg(struct device *dev, int blk_num)
|
|||||||
attr->nr = blk_num;
|
attr->nr = blk_num;
|
||||||
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||||
events[j].evt_name);
|
events[j].evt_name);
|
||||||
|
if (!attr->dev_attr.attr.name)
|
||||||
|
return -ENOMEM;
|
||||||
pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;
|
pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;
|
||||||
attr = NULL;
|
attr = NULL;
|
||||||
i++;
|
i++;
|
||||||
@ -1882,6 +1892,8 @@ static int mlxbf_pmc_create_groups(struct device *dev, int blk_num)
|
|||||||
pmc->block[blk_num].block_attr_grp.attrs = pmc->block[blk_num].block_attr;
|
pmc->block[blk_num].block_attr_grp.attrs = pmc->block[blk_num].block_attr;
|
||||||
pmc->block[blk_num].block_attr_grp.name = devm_kasprintf(
|
pmc->block[blk_num].block_attr_grp.name = devm_kasprintf(
|
||||||
dev, GFP_KERNEL, pmc->block_name[blk_num]);
|
dev, GFP_KERNEL, pmc->block_name[blk_num]);
|
||||||
|
if (!pmc->block[blk_num].block_attr_grp.name)
|
||||||
|
return -ENOMEM;
|
||||||
pmc->groups[pmc->group_num] = &pmc->block[blk_num].block_attr_grp;
|
pmc->groups[pmc->group_num] = &pmc->block[blk_num].block_attr_grp;
|
||||||
pmc->group_num++;
|
pmc->group_num++;
|
||||||
|
|
||||||
@ -2063,6 +2075,8 @@ static int mlxbf_pmc_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
pmc->hwmon_dev = devm_hwmon_device_register_with_groups(
|
pmc->hwmon_dev = devm_hwmon_device_register_with_groups(
|
||||||
dev, "bfperf", pmc, pmc->groups);
|
dev, "bfperf", pmc, pmc->groups);
|
||||||
|
if (IS_ERR(pmc->hwmon_dev))
|
||||||
|
return PTR_ERR(pmc->hwmon_dev);
|
||||||
platform_set_drvdata(pdev, pmc);
|
platform_set_drvdata(pdev, pmc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -231,9 +231,12 @@ static int ssam_receive_buf(struct serdev_device *dev, const unsigned char *buf,
|
|||||||
size_t n)
|
size_t n)
|
||||||
{
|
{
|
||||||
struct ssam_controller *ctrl;
|
struct ssam_controller *ctrl;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ctrl = serdev_device_get_drvdata(dev);
|
ctrl = serdev_device_get_drvdata(dev);
|
||||||
return ssam_controller_receive_buf(ctrl, buf, n);
|
ret = ssam_controller_receive_buf(ctrl, buf, n);
|
||||||
|
|
||||||
|
return ret < 0 ? 0 : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ssam_write_wakeup(struct serdev_device *dev)
|
static void ssam_write_wakeup(struct serdev_device *dev)
|
||||||
|
@ -263,6 +263,7 @@ config ASUS_WMI
|
|||||||
depends on RFKILL || RFKILL = n
|
depends on RFKILL || RFKILL = n
|
||||||
depends on HOTPLUG_PCI
|
depends on HOTPLUG_PCI
|
||||||
depends on ACPI_VIDEO || ACPI_VIDEO = n
|
depends on ACPI_VIDEO || ACPI_VIDEO = n
|
||||||
|
depends on SERIO_I8042 || SERIO_I8042 = n
|
||||||
select INPUT_SPARSEKMAP
|
select INPUT_SPARSEKMAP
|
||||||
select LEDS_CLASS
|
select LEDS_CLASS
|
||||||
select NEW_LEDS
|
select NEW_LEDS
|
||||||
@ -279,7 +280,6 @@ config ASUS_WMI
|
|||||||
config ASUS_NB_WMI
|
config ASUS_NB_WMI
|
||||||
tristate "Asus Notebook WMI Driver"
|
tristate "Asus Notebook WMI Driver"
|
||||||
depends on ASUS_WMI
|
depends on ASUS_WMI
|
||||||
depends on SERIO_I8042 || SERIO_I8042 = n
|
|
||||||
help
|
help
|
||||||
This is a driver for newer Asus notebooks. It adds extra features
|
This is a driver for newer Asus notebooks. It adds extra features
|
||||||
like wireless radio and bluetooth control, leds, hotkeys, backlight...
|
like wireless radio and bluetooth control, leds, hotkeys, backlight...
|
||||||
|
@ -48,25 +48,43 @@ module_param(tablet_mode_sw, uint, 0444);
|
|||||||
MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip 3:lid-flip-rog");
|
MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip 3:lid-flip-rog");
|
||||||
|
|
||||||
static struct quirk_entry *quirks;
|
static struct quirk_entry *quirks;
|
||||||
|
static bool atkbd_reports_vol_keys;
|
||||||
|
|
||||||
static bool asus_q500a_i8042_filter(unsigned char data, unsigned char str,
|
static bool asus_i8042_filter(unsigned char data, unsigned char str, struct serio *port)
|
||||||
struct serio *port)
|
|
||||||
{
|
{
|
||||||
static bool extended;
|
static bool extended_e0;
|
||||||
bool ret = false;
|
static bool extended_e1;
|
||||||
|
|
||||||
if (str & I8042_STR_AUXDATA)
|
if (str & I8042_STR_AUXDATA)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (unlikely(data == 0xe1)) {
|
if (quirks->filter_i8042_e1_extended_codes) {
|
||||||
extended = true;
|
if (data == 0xe1) {
|
||||||
ret = true;
|
extended_e1 = true;
|
||||||
} else if (unlikely(extended)) {
|
return true;
|
||||||
extended = false;
|
}
|
||||||
ret = true;
|
|
||||||
|
if (extended_e1) {
|
||||||
|
extended_e1 = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
if (data == 0xe0) {
|
||||||
|
extended_e0 = true;
|
||||||
|
} else if (extended_e0) {
|
||||||
|
extended_e0 = false;
|
||||||
|
|
||||||
|
switch (data & 0x7f) {
|
||||||
|
case 0x20: /* e0 20 / e0 a0, Volume Mute press / release */
|
||||||
|
case 0x2e: /* e0 2e / e0 ae, Volume Down press / release */
|
||||||
|
case 0x30: /* e0 30 / e0 b0, Volume Up press / release */
|
||||||
|
atkbd_reports_vol_keys = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct quirk_entry quirk_asus_unknown = {
|
static struct quirk_entry quirk_asus_unknown = {
|
||||||
@ -75,7 +93,7 @@ static struct quirk_entry quirk_asus_unknown = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct quirk_entry quirk_asus_q500a = {
|
static struct quirk_entry quirk_asus_q500a = {
|
||||||
.i8042_filter = asus_q500a_i8042_filter,
|
.filter_i8042_e1_extended_codes = true,
|
||||||
.wmi_backlight_set_devstate = true,
|
.wmi_backlight_set_devstate = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -503,8 +521,6 @@ static const struct dmi_system_id asus_quirks[] = {
|
|||||||
|
|
||||||
static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
|
static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
quirks = &quirk_asus_unknown;
|
quirks = &quirk_asus_unknown;
|
||||||
dmi_check_system(asus_quirks);
|
dmi_check_system(asus_quirks);
|
||||||
|
|
||||||
@ -519,15 +535,6 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
|
|||||||
|
|
||||||
if (tablet_mode_sw != -1)
|
if (tablet_mode_sw != -1)
|
||||||
quirks->tablet_switch_mode = tablet_mode_sw;
|
quirks->tablet_switch_mode = tablet_mode_sw;
|
||||||
|
|
||||||
if (quirks->i8042_filter) {
|
|
||||||
ret = i8042_install_filter(quirks->i8042_filter);
|
|
||||||
if (ret) {
|
|
||||||
pr_warn("Unable to install key filter\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pr_info("Using i8042 filter function for receiving events\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct key_entry asus_nb_wmi_keymap[] = {
|
static const struct key_entry asus_nb_wmi_keymap[] = {
|
||||||
@ -617,6 +624,13 @@ static void asus_nb_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code,
|
|||||||
if (acpi_video_handles_brightness_key_presses())
|
if (acpi_video_handles_brightness_key_presses())
|
||||||
*code = ASUS_WMI_KEY_IGNORE;
|
*code = ASUS_WMI_KEY_IGNORE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x30: /* Volume Up */
|
||||||
|
case 0x31: /* Volume Down */
|
||||||
|
case 0x32: /* Volume Mute */
|
||||||
|
if (atkbd_reports_vol_keys)
|
||||||
|
*code = ASUS_WMI_KEY_IGNORE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,6 +644,7 @@ static struct asus_wmi_driver asus_nb_wmi_driver = {
|
|||||||
.input_phys = ASUS_NB_WMI_FILE "/input0",
|
.input_phys = ASUS_NB_WMI_FILE "/input0",
|
||||||
.detect_quirks = asus_nb_wmi_quirks,
|
.detect_quirks = asus_nb_wmi_quirks,
|
||||||
.key_filter = asus_nb_wmi_key_filter,
|
.key_filter = asus_nb_wmi_key_filter,
|
||||||
|
.i8042_filter = asus_i8042_filter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/backlight.h>
|
#include <linux/backlight.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
#include <linux/hwmon.h>
|
#include <linux/hwmon.h>
|
||||||
@ -132,6 +133,11 @@ module_param(fnlock_default, bool, 0444);
|
|||||||
#define ASUS_SCREENPAD_BRIGHT_MAX 255
|
#define ASUS_SCREENPAD_BRIGHT_MAX 255
|
||||||
#define ASUS_SCREENPAD_BRIGHT_DEFAULT 60
|
#define ASUS_SCREENPAD_BRIGHT_DEFAULT 60
|
||||||
|
|
||||||
|
/* Controls the power state of the USB0 hub on ROG Ally which input is on */
|
||||||
|
#define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE"
|
||||||
|
/* 300ms so far seems to produce a reliable result on AC and battery */
|
||||||
|
#define ASUS_USB0_PWR_EC0_CSEE_WAIT 300
|
||||||
|
|
||||||
static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
|
static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
|
||||||
|
|
||||||
static int throttle_thermal_policy_write(struct asus_wmi *);
|
static int throttle_thermal_policy_write(struct asus_wmi *);
|
||||||
@ -300,6 +306,9 @@ struct asus_wmi {
|
|||||||
|
|
||||||
bool fnlock_locked;
|
bool fnlock_locked;
|
||||||
|
|
||||||
|
/* The ROG Ally device requires the MCU USB device be disconnected before suspend */
|
||||||
|
bool ally_mcu_usb_switch;
|
||||||
|
|
||||||
struct asus_wmi_debug debug;
|
struct asus_wmi_debug debug;
|
||||||
|
|
||||||
struct asus_wmi_driver *driver;
|
struct asus_wmi_driver *driver;
|
||||||
@ -4488,6 +4497,8 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|||||||
asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET);
|
asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET);
|
||||||
asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
|
asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
|
||||||
asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
|
asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
|
||||||
|
asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
|
||||||
|
&& dmi_match(DMI_BOARD_NAME, "RC71L");
|
||||||
|
|
||||||
err = fan_boost_mode_check_present(asus);
|
err = fan_boost_mode_check_present(asus);
|
||||||
if (err)
|
if (err)
|
||||||
@ -4567,6 +4578,12 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|||||||
goto fail_wmi_handler;
|
goto fail_wmi_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (asus->driver->i8042_filter) {
|
||||||
|
err = i8042_install_filter(asus->driver->i8042_filter);
|
||||||
|
if (err)
|
||||||
|
pr_warn("Unable to install key filter - %d\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
asus_wmi_battery_init(asus);
|
asus_wmi_battery_init(asus);
|
||||||
|
|
||||||
asus_wmi_debugfs_init(asus);
|
asus_wmi_debugfs_init(asus);
|
||||||
@ -4603,6 +4620,8 @@ static int asus_wmi_remove(struct platform_device *device)
|
|||||||
struct asus_wmi *asus;
|
struct asus_wmi *asus;
|
||||||
|
|
||||||
asus = platform_get_drvdata(device);
|
asus = platform_get_drvdata(device);
|
||||||
|
if (asus->driver->i8042_filter)
|
||||||
|
i8042_remove_filter(asus->driver->i8042_filter);
|
||||||
wmi_remove_notify_handler(asus->driver->event_guid);
|
wmi_remove_notify_handler(asus->driver->event_guid);
|
||||||
asus_wmi_backlight_exit(asus);
|
asus_wmi_backlight_exit(asus);
|
||||||
asus_screenpad_exit(asus);
|
asus_screenpad_exit(asus);
|
||||||
@ -4654,6 +4673,43 @@ static int asus_hotk_resume(struct device *device)
|
|||||||
asus_wmi_fnlock_update(asus);
|
asus_wmi_fnlock_update(asus);
|
||||||
|
|
||||||
asus_wmi_tablet_mode_get_state(asus);
|
asus_wmi_tablet_mode_get_state(asus);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int asus_hotk_resume_early(struct device *device)
|
||||||
|
{
|
||||||
|
struct asus_wmi *asus = dev_get_drvdata(device);
|
||||||
|
|
||||||
|
if (asus->ally_mcu_usb_switch) {
|
||||||
|
if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8)))
|
||||||
|
dev_err(device, "ROG Ally MCU failed to connect USB dev\n");
|
||||||
|
else
|
||||||
|
msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int asus_hotk_prepare(struct device *device)
|
||||||
|
{
|
||||||
|
struct asus_wmi *asus = dev_get_drvdata(device);
|
||||||
|
int result, err;
|
||||||
|
|
||||||
|
if (asus->ally_mcu_usb_switch) {
|
||||||
|
/* When powersave is enabled it causes many issues with resume of USB hub */
|
||||||
|
result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MCU_POWERSAVE);
|
||||||
|
if (result == 1) {
|
||||||
|
dev_warn(device, "MCU powersave enabled, disabling to prevent resume issues");
|
||||||
|
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, 0, &result);
|
||||||
|
if (err || result != 1)
|
||||||
|
dev_err(device, "Failed to set MCU powersave mode: %d\n", err);
|
||||||
|
}
|
||||||
|
/* sleep required to ensure USB0 is disabled before sleep continues */
|
||||||
|
if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7)))
|
||||||
|
dev_err(device, "ROG Ally MCU failed to disconnect USB dev\n");
|
||||||
|
else
|
||||||
|
msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4701,6 +4757,8 @@ static const struct dev_pm_ops asus_pm_ops = {
|
|||||||
.thaw = asus_hotk_thaw,
|
.thaw = asus_hotk_thaw,
|
||||||
.restore = asus_hotk_restore,
|
.restore = asus_hotk_restore,
|
||||||
.resume = asus_hotk_resume,
|
.resume = asus_hotk_resume,
|
||||||
|
.resume_early = asus_hotk_resume_early,
|
||||||
|
.prepare = asus_hotk_prepare,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Registration ***************************************************************/
|
/* Registration ***************************************************************/
|
||||||
|
@ -39,6 +39,7 @@ struct quirk_entry {
|
|||||||
bool wmi_backlight_set_devstate;
|
bool wmi_backlight_set_devstate;
|
||||||
bool wmi_force_als_set;
|
bool wmi_force_als_set;
|
||||||
bool wmi_ignore_fan;
|
bool wmi_ignore_fan;
|
||||||
|
bool filter_i8042_e1_extended_codes;
|
||||||
enum asus_wmi_tablet_switch_mode tablet_switch_mode;
|
enum asus_wmi_tablet_switch_mode tablet_switch_mode;
|
||||||
int wapf;
|
int wapf;
|
||||||
/*
|
/*
|
||||||
@ -49,9 +50,6 @@ struct quirk_entry {
|
|||||||
*/
|
*/
|
||||||
int no_display_toggle;
|
int no_display_toggle;
|
||||||
u32 xusb2pr;
|
u32 xusb2pr;
|
||||||
|
|
||||||
bool (*i8042_filter)(unsigned char data, unsigned char str,
|
|
||||||
struct serio *serio);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct asus_wmi_driver {
|
struct asus_wmi_driver {
|
||||||
@ -73,6 +71,9 @@ struct asus_wmi_driver {
|
|||||||
* Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */
|
* Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */
|
||||||
void (*key_filter) (struct asus_wmi_driver *driver, int *code,
|
void (*key_filter) (struct asus_wmi_driver *driver, int *code,
|
||||||
unsigned int *value, bool *autorelease);
|
unsigned int *value, bool *autorelease);
|
||||||
|
/* Optional standard i8042 filter */
|
||||||
|
bool (*i8042_filter)(unsigned char data, unsigned char str,
|
||||||
|
struct serio *serio);
|
||||||
|
|
||||||
int (*probe) (struct platform_device *device);
|
int (*probe) (struct platform_device *device);
|
||||||
void (*detect_quirks) (struct asus_wmi_driver *driver);
|
void (*detect_quirks) (struct asus_wmi_driver *driver);
|
||||||
|
@ -1340,6 +1340,11 @@ static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev)
|
|||||||
if (debug_dump_wdg)
|
if (debug_dump_wdg)
|
||||||
wmi_dump_wdg(&gblock[i]);
|
wmi_dump_wdg(&gblock[i]);
|
||||||
|
|
||||||
|
if (!gblock[i].instance_count) {
|
||||||
|
dev_info(wmi_bus_dev, FW_INFO "%pUL has zero instances\n", &gblock[i].guid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (guid_already_parsed_for_legacy(device, &gblock[i].guid))
|
if (guid_already_parsed_for_legacy(device, &gblock[i].guid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -114,6 +114,9 @@
|
|||||||
/* Charging mode - 1=Barrel, 2=USB */
|
/* Charging mode - 1=Barrel, 2=USB */
|
||||||
#define ASUS_WMI_DEVID_CHARGE_MODE 0x0012006C
|
#define ASUS_WMI_DEVID_CHARGE_MODE 0x0012006C
|
||||||
|
|
||||||
|
/* MCU powersave mode */
|
||||||
|
#define ASUS_WMI_DEVID_MCU_POWERSAVE 0x001200E2
|
||||||
|
|
||||||
/* epu is connected? 1 == true */
|
/* epu is connected? 1 == true */
|
||||||
#define ASUS_WMI_DEVID_EGPU_CONNECTED 0x00090018
|
#define ASUS_WMI_DEVID_EGPU_CONNECTED 0x00090018
|
||||||
/* egpu on/off */
|
/* egpu on/off */
|
||||||
|
Loading…
Reference in New Issue
Block a user