This commit is contained in:
Ward from fusion-voyager-3 2023-12-12 14:10:53 +03:00
parent 7ec6356373
commit 169be065dc
27 changed files with 23423 additions and 3559 deletions

View File

@ -1 +1 @@
6.6 6.6.6

View File

@ -1,109 +0,0 @@
From 34713cb8d4e13bf9e3b1403cdea9551e0532ec5c Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
Date: Wed, 23 Aug 2023 11:05:59 +1200
Subject: [PATCH v2 2/2] ALSA: hda: cs35l41: Support ASUS 2023 laptops with
missing DSD
Support adding the missing DSD properties required for ASUS ROG 2023
laptops and other ASUS laptops to properly utilise the cs35l41.
The currently added laptops are:
- ASUS GS650P, i2c
- ASUS GA402X, i2c
- ASUS GU604V, spi
- ASUS GU603V, spi
- ASUS GV601V, spi
- ASUS GZ301V, spi
- ASUS ROG ALLY, i2c
- ASUS G614J, spi
- ASUS G634J, spi
- ASUS G614JI, spi
- ASUS G713P, i2c
- ASUS H7604JV, spi
The SPI connected amps may be required to use an external DSD patch
to fix or add the "cs-gpios" property.
Co-developed-by: Jonathan LoBue <jlobue10@gmail.com>
Signed-off-by: Jonathan LoBue <jlobue10@gmail.com>
Co-developed-by: Luke D. Jones <luke@ljones.dev>
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
sound/pci/hda/cs35l41_hda_property.c | 53 ++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index 673f23257a09..b06e8ca5f4b4 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -43,6 +43,47 @@ static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy
return 0;
}
+/*
+ * The CSC3551 is used in almost the entire ASUS ROG laptop range in 2023, this is likely to
+ * also include many non ROG labelled laptops. It is also used with either I2C connection or
+ * SPI connection. The SPI connected versions may be missing a chip select GPIO and require
+ * an DSD table patch.
+ */
+static int asus_rog_2023_spkr_id2(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
+ const char *hid)
+{
+ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
+ int reset_gpio = 0;
+ int spkr_gpio = 2;
+
+ /* check SPI or I2C address to assign the index */
+ cs35l41->index = (id == 0 || id == 0x40) ? 0 : 1;
+ cs35l41->channel_index = 0;
+ hw_cfg->spk_pos = cs35l41->index;
+ hw_cfg->bst_type = CS35L41_EXT_BOOST;
+ hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
+ hw_cfg->gpio1.valid = true;
+ hw_cfg->gpio2.func = CS35L41_INTERRUPT;
+ hw_cfg->gpio2.valid = true;
+
+ if (strcmp(cs35l41->acpi_subsystem_id, "10431483") == 0)
+ spkr_gpio = 1;
+ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, spkr_gpio);
+
+ if (strcmp(cs35l41->acpi_subsystem_id, "10431463") == 0)
+ reset_gpio = 0;
+ else if (strcmp(cs35l41->acpi_subsystem_id, "10431473") == 0
+ || strcmp(cs35l41->acpi_subsystem_id, "10431483") == 0
+ || strcmp(cs35l41->acpi_subsystem_id, "10431493") == 0) {
+ reset_gpio = 1;
+ }
+ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, reset_gpio, GPIOD_OUT_HIGH);
+
+ hw_cfg->valid = true;
+
+ return 0;
+}
+
struct cs35l41_prop_model {
const char *hid;
const char *ssid;
@@ -53,6 +94,18 @@ struct cs35l41_prop_model {
const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CLSA0100", NULL, lenovo_legion_no_acpi },
{ "CLSA0101", NULL, lenovo_legion_no_acpi },
{ "CSC3551", "103C89C6", hp_vision_acpi_fix },
+ { "CSC3551", "10431433", asus_rog_2023_spkr_id2 }, // ASUS GS650P - i2c
+ { "CSC3551", "10431463", asus_rog_2023_spkr_id2 }, // ASUS GA402X/N - i2c, reset gpio 0
+ { "CSC3551", "10431473", asus_rog_2023_spkr_id2 }, // ASUS GU604V - spi, reset gpio 1
+ { "CSC3551", "10431483", asus_rog_2023_spkr_id2 }, // ASUS GU603V - spi, reset 1, spkr 1
+ { "CSC3551", "10431493", asus_rog_2023_spkr_id2 }, // ASUS GV601V - spi, reset gpio 1
+ { "CSC3551", "10431573", asus_rog_2023_spkr_id2 }, // ASUS GZ301V - spi, reset gpio 0
+ { "CSC3551", "104317F3", asus_rog_2023_spkr_id2 }, // ASUS ROG ALLY - i2c
+ { "CSC3551", "10431B93", asus_rog_2023_spkr_id2 }, // ASUS G614J - spi, reset gpio 0
+ { "CSC3551", "10431CAF", asus_rog_2023_spkr_id2 }, // ASUS G634J - spi, reset gpio 0
+ { "CSC3551", "10431C9F", asus_rog_2023_spkr_id2 }, // ASUS G614JI -spi, reset gpio 0
+ { "CSC3551", "10431D1F", asus_rog_2023_spkr_id2 }, // ASUS G713P - i2c
+ { "CSC3551", "10431F1F", asus_rog_2023_spkr_id2 }, // ASUS H7604JV - spi, reset gpio 0
{}
};
--
2.41.0

View File

@ -0,0 +1,12 @@
diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c
index 81bf03d..96d875b 100644
--- a/drivers/hwmon/nct6775-platform.c
+++ b/drivers/hwmon/nct6775-platform.c
@@ -1359,6 +1359,7 @@ static const char * const asus_msi_boards[] = {
"ProArt X670E-CREATOR WIFI",
"ProArt Z690-CREATOR WIFI",
"ProArt Z790-CREATOR WIFI",
+ "RC71L",
"ROG CROSSHAIR X670E EXTREME",
"ROG CROSSHAIR X670E GENE",
"ROG CROSSHAIR X670E HERO",

View File

@ -1,181 +0,0 @@
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
index bdb578e0899f..f98a02eee783 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -146,6 +146,8 @@ static const char *get_sensor_name(int idx)
return "gyroscope";
case mag_idx:
return "magnetometer";
+ case tms_idx:
+ return "tablet-mode-switch";
case als_idx:
case ACS_IDX: /* ambient color sensor */
return "ALS";
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
index 97296f587bc7..cea7ec6f6288 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
@@ -11,7 +11,7 @@
#ifndef AMDSFH_HID_H
#define AMDSFH_HID_H
-#define MAX_HID_DEVICES 6
+#define MAX_HID_DEVICES 7
#define AMD_SFH_HID_VENDOR 0x1022
#define AMD_SFH_HID_PRODUCT 0x0001
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index 2530fa98b568..af5b37a62b10 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -27,6 +27,7 @@
#define ACEL_EN BIT(0)
#define GYRO_EN BIT(1)
#define MAGNO_EN BIT(2)
+#define TMS_EN BIT(15)
#define HPD_EN BIT(16)
#define ALS_EN BIT(19)
#define ACS_EN BIT(22)
@@ -228,6 +229,9 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
if (MAGNO_EN & activestatus)
sensor_id[num_of_sensors++] = mag_idx;
+ if (TMS_EN & activestatus)
+ sensor_id[num_of_sensors++] = tms_idx;
+
if (ALS_EN & activestatus)
sensor_id[num_of_sensors++] = als_idx;
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
index 70add75fc506..60130ad846a4 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
@@ -79,6 +79,7 @@ enum sensor_idx {
accel_idx = 0,
gyro_idx = 1,
mag_idx = 2,
+ tms_idx = 15,
als_idx = 19
};
diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
index 8716a05950c8..b6725e8daf0c 100644
--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
@@ -47,6 +47,11 @@ static int get_report_descriptor(int sensor_idx, u8 *rep_desc)
memcpy(rep_desc, comp3_report_descriptor,
sizeof(comp3_report_descriptor));
break;
+ case tms_idx: /* tablet mode switch */
+ memset(rep_desc, 0, sizeof(tms_report_descriptor));
+ memcpy(rep_desc, tms_report_descriptor,
+ sizeof(tms_report_descriptor));
+ break;
case als_idx: /* ambient light sensor */
case ACS_IDX: /* ambient color sensor */
memset(rep_desc, 0, sizeof(als_report_descriptor));
@@ -97,6 +102,16 @@ static u32 get_descr_sz(int sensor_idx, int descriptor_name)
return sizeof(struct magno_feature_report);
}
break;
+ case tms_idx:
+ switch (descriptor_name) {
+ case descr_size:
+ return sizeof(tms_report_descriptor);
+ case input_size:
+ return sizeof(struct tms_input_report);
+ case feature_size:
+ return sizeof(struct tms_feature_report);
+ }
+ break;
case als_idx:
case ACS_IDX: /* ambient color sensor */
switch (descriptor_name) {
@@ -140,6 +155,7 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
struct accel3_feature_report acc_feature;
struct gyro_feature_report gyro_feature;
struct magno_feature_report magno_feature;
+ struct tms_feature_report tms_feature;
struct hpd_feature_report hpd_feature;
struct als_feature_report als_feature;
u8 report_size = 0;
@@ -175,6 +191,11 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
memcpy(feature_report, &magno_feature, sizeof(magno_feature));
report_size = sizeof(magno_feature);
break;
+ case tms_idx: /* tablet mode switch */
+ get_common_features(&tms_feature.common_property, report_id);
+ memcpy(feature_report, &tms_feature, sizeof(tms_feature));
+ report_size = sizeof(tms_feature);
+ break;
case als_idx: /* ambient light sensor */
case ACS_IDX: /* ambient color sensor */
get_common_features(&als_feature.common_property, report_id);
@@ -214,6 +235,7 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
struct accel3_input_report acc_input;
struct gyro_input_report gyro_input;
struct hpd_input_report hpd_input;
+ struct tms_input_report tms_input;
struct als_input_report als_input;
struct hpd_status hpdstatus;
u8 report_size = 0;
@@ -247,6 +269,11 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
memcpy(input_report, &magno_input, sizeof(magno_input));
report_size = sizeof(magno_input);
break;
+ case tms_idx: /* tablet mode switch */
+ get_common_inputs(&tms_input.common_property, report_id);
+ report_size = sizeof(tms_input);
+ memcpy(input_report, &tms_input, sizeof(tms_input));
+ break;
case als_idx: /* Als */
case ACS_IDX: /* ambient color sensor */
get_common_inputs(&als_input.common_property, report_id);
diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
index ebd55675eb62..b22068a47429 100644
--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
@@ -111,4 +111,11 @@ struct hpd_input_report {
u8 human_presence;
} __packed;
+struct tms_feature_report {
+ struct common_feature_property common_property;
+} __packed;
+
+struct tms_input_report {
+ struct common_input_property common_property;
+} __packed;
#endif
diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
index 697f2791ea9c..96cbc1e5b9a7 100644
--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
@@ -644,6 +644,27 @@ static const u8 als_report_descriptor[] = {
0xC0 /* HID end collection */
};
+
+/* TABLET MODE SWITCH */
+__maybe_unused // Used by sfh1.0, but not yet implemented in sfh1.1
+static const u8 tms_report_descriptor[] = {
+0x06, 0x43, 0xFF, // Usage Page (Vendor Defined 0xFF43)
+0x0A, 0x02, 0x02, // Usage (0x0202)
+0xA1, 0x01, // Collection (Application)
+0x85, 0x11, // Report ID (17)
+0x15, 0x00, // Logical Minimum (0)
+0x25, 0x01, // Logical Maximum (1)
+0x35, 0x00, // Physical Minimum (0)
+0x45, 0x01, // Physical Maximum (1)
+0x65, 0x00, // Unit (None)
+0x55, 0x00, // Unit Exponent (0)
+0x75, 0x01, // Report Size (1)
+0x95, 0x98, // Report Count (-104)
+0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+0xC1, 0x00, // End Collection
+};
+
/* BIOMETRIC PRESENCE*/
static const u8 hpd_report_descriptor[] = {
0x05, 0x20, /* Usage page */

View File

@ -1,3 +1,115 @@
From 76556b655f7b50afe5c58006f44221900e5711a9 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
Date: Wed, 23 Aug 2023 11:05:59 +1200
Subject: [PATCH v2] ALSA: hda: cs35l41: Support ASUS 2023 laptops with missing
DSD
Support adding the missing DSD properties required for ASUS ROG 2023
laptops and other ASUS laptops to properly utilise the cs35l41.
The currently added laptops are:
- ASUS GS650P, i2c
- ASUS GA402X, i2c
- ASUS GU604V, spi
- ASUS GU603V, spi
- ASUS GV601V, spi
- ASUS GZ301V, spi
- ASUS ROG ALLY, i2c
- ASUS G614J, spi
- ASUS G634J, spi
- ASUS G614JI, spi
- ASUS G713P, i2c
- ASUS H7604JV, spi
The SPI connected amps may be required to use an external DSD patch
to fix or add the "cs-gpios" property.
Co-developed-by: Jonathan LoBue <jlobue10@gmail.com>
Signed-off-by: Jonathan LoBue <jlobue10@gmail.com>
Co-developed-by: Luke D. Jones <luke@ljones.dev>
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
sound/pci/hda/cs35l41_hda_property.c | 57 ++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index c83328971728..de0802859849 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -76,6 +76,49 @@ static int hp_vision_acpi_fix(struct cs35l41_hda *cs35l41, struct device *physde
hw_cfg->bst_ind = 1000;
hw_cfg->bst_ipk = 4500;
hw_cfg->bst_cap = 24;
+
+ hw_cfg->valid = true;
+
+ return 0;
+}
+
+/*
+ * The CSC3551 is used in almost the entire ROG laptop range in 2023, this is likely to
+ * also include many non ROG labelled laptops. It is also used with either I2C connection or
+ * SPI connection. The SPI connected versions may be missing a chip select GPIO and require
+ * an DSD table patch.
+ */
+static int asus_rog_2023_no_acpi(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
+ const char *hid)
+{
+ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
+ int reset_gpio = 0;
+ int spkr_gpio = 2;
+
+ /* check SPI or I2C address to assign the index */
+ cs35l41->index = (id == 0 || id == 0x40) ? 0 : 1;
+ cs35l41->channel_index = 0;
+ hw_cfg->spk_pos = cs35l41->index;
+ hw_cfg->bst_type = CS35L41_EXT_BOOST;
+ hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
+ hw_cfg->gpio1.valid = true;
+ hw_cfg->gpio2.func = CS35L41_INTERRUPT;
+ hw_cfg->gpio2.valid = true;
+
+ if (strcmp(cs35l41->acpi_subsystem_id, "10431483") == 0)
+ spkr_gpio = 1;
+ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, spkr_gpio);
+
+ if (strcmp(cs35l41->acpi_subsystem_id, "10431473") == 0
+ || strcmp(cs35l41->acpi_subsystem_id, "10431483") == 0
+ || strcmp(cs35l41->acpi_subsystem_id, "10431493") == 0
+ || strcmp(cs35l41->acpi_subsystem_id, "10431CAF") == 0
+ || strcmp(cs35l41->acpi_subsystem_id, "10431CCF") == 0
+ || strcmp(cs35l41->acpi_subsystem_id, "10431E02") == 0) {
+ reset_gpio = 1;
+ }
+ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, reset_gpio, GPIOD_OUT_HIGH);
+
hw_cfg->valid = true;
return 0;
@@ -92,6 +135,20 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CLSA0100", NULL, lenovo_legion_no_acpi },
{ "CLSA0101", NULL, lenovo_legion_no_acpi },
{ "CSC3551", "103C89C6", hp_vision_acpi_fix },
+ { "CSC3551", "10431433", asus_rog_2023_no_acpi }, // GS650P i2c
+ { "CSC3551", "10431463", asus_rog_2023_no_acpi }, // GA402X/N i2c, rst=0
+ { "CSC3551", "10431473", asus_rog_2023_no_acpi }, // GU604V spi, rst=1
+ { "CSC3551", "10431483", asus_rog_2023_no_acpi }, // GU603V spi, rst=1, spkr=1
+ { "CSC3551", "10431493", asus_rog_2023_no_acpi }, // GV601V spi, rst=1
+ { "CSC3551", "10431573", asus_rog_2023_no_acpi }, // GZ301V spi, rst=0
+ { "CSC3551", "104317F3", asus_rog_2023_no_acpi }, // ROG ALLY i2c, rst=0
+ { "CSC3551", "10431B93", asus_rog_2023_no_acpi }, // G614J spi, rst=0
+ { "CSC3551", "10431C9F", asus_rog_2023_no_acpi }, // G614JI spi, rst=0
+ { "CSC3551", "10431CAF", asus_rog_2023_no_acpi }, // G634J spi, rst=1
+ { "CSC3551", "10431CCF", asus_rog_2023_no_acpi }, // G814J spi, rst=1
+ { "CSC3551", "10431D1F", asus_rog_2023_no_acpi }, // G713P i2c, rst=0
+ { "CSC3551", "10431E02", asus_rog_2023_no_acpi }, // UX3042Z spi, rst=1
+ { "CSC3551", "10431F1F", asus_rog_2023_no_acpi }, // H7604JV spi, rst=0
{}
};
--
2.41.0
From b35a4c957b3f0e5b4c7c73dec4fe3a5b9dbc4873 Mon Sep 17 00:00:00 2001 From b35a4c957b3f0e5b4c7c73dec4fe3a5b9dbc4873 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev> From: "Luke D. Jones" <luke@ljones.dev>
Date: Sun, 30 Apr 2023 10:56:34 +1200 Date: Sun, 30 Apr 2023 10:56:34 +1200
@ -45,26 +157,26 @@ index f54178d6f780..0b13be703856 100644
@@ -127,6 +128,10 @@ module_param(fnlock_default, bool, 0444); @@ -127,6 +128,10 @@ module_param(fnlock_default, bool, 0444);
#define NVIDIA_TEMP_MIN 75 #define NVIDIA_TEMP_MIN 75
#define NVIDIA_TEMP_MAX 87 #define NVIDIA_TEMP_MAX 87
+#define ASUS_SCREENPAD_BRIGHT_MIN 20 +#define ASUS_SCREENPAD_BRIGHT_MIN 20
+#define ASUS_SCREENPAD_BRIGHT_MAX 255 +#define ASUS_SCREENPAD_BRIGHT_MAX 255
+#define ASUS_SCREENPAD_BRIGHT_DEFAULT 60 +#define ASUS_SCREENPAD_BRIGHT_DEFAULT 60
+ +
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 *);
@@ -212,6 +217,7 @@ struct asus_wmi { @@ -212,6 +217,7 @@ struct asus_wmi {
struct input_dev *inputdev; struct input_dev *inputdev;
struct backlight_device *backlight_device; struct backlight_device *backlight_device;
+ struct backlight_device *screenpad_backlight_device; + struct backlight_device *screenpad_backlight_device;
struct platform_device *platform_device; struct platform_device *platform_device;
struct led_classdev wlan_led; struct led_classdev wlan_led;
@@ -3776,6 +3782,124 @@ static int is_display_toggle(int code) @@ -3776,6 +3782,124 @@ static int is_display_toggle(int code)
return 0; return 0;
} }
+/* Screenpad backlight *******************************************************/ +/* Screenpad backlight *******************************************************/
+ +
+static int read_screenpad_backlight_power(struct asus_wmi *asus) +static int read_screenpad_backlight_power(struct asus_wmi *asus)
@ -184,12 +296,12 @@ index f54178d6f780..0b13be703856 100644
+} +}
+ +
/* Fn-lock ********************************************************************/ /* Fn-lock ********************************************************************/
static bool asus_wmi_has_fnlock_key(struct asus_wmi *asus) static bool asus_wmi_has_fnlock_key(struct asus_wmi *asus)
@@ -4431,6 +4555,12 @@ static int asus_wmi_add(struct platform_device *pdev) @@ -4431,6 +4555,12 @@ static int asus_wmi_add(struct platform_device *pdev)
} else if (asus->driver->quirks->wmi_backlight_set_devstate) } else if (asus->driver->quirks->wmi_backlight_set_devstate)
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, 2, NULL); err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, 2, NULL);
+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_SCREENPAD_LIGHT)) { + if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_SCREENPAD_LIGHT)) {
+ err = asus_screenpad_init(asus); + err = asus_screenpad_init(asus);
+ if (err && err != -ENODEV) + if (err && err != -ENODEV)
@ -226,7 +338,7 @@ index a478ebfd34df..5fbdd0eafa02 100644
int panel_power; int panel_power;
+ int screenpad_brightness; + int screenpad_brightness;
int wlan_ctrl_by_user; int wlan_ctrl_by_user;
const char *name; const char *name;
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index 16e99a1c37fc..63e630276499 100644 index 16e99a1c37fc..63e630276499 100644
@ -242,7 +354,37 @@ index 16e99a1c37fc..63e630276499 100644
+#define ASUS_WMI_DEVID_SCREENPAD_LIGHT 0x00050032 +#define ASUS_WMI_DEVID_SCREENPAD_LIGHT 0x00050032
#define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018 #define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018
#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075 #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075
-- --
2.41.0 2.41.0
From 7760e10674dbb9127450629308c6ee1c35d5fc19 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
Date: Thu, 9 Nov 2023 09:41:13 +1300
Subject: [PATCH] ALSA: hda/realtek: Add quirk for ASUS ROG G814Jx
Adds the required quirk to enable the Cirrus amp and correct pins
on the ASUS ROG G814J series which uses an SPI connected Cirrus amp.
While this works if the related _DSD properties are made available, these
aren't included in the ACPI of these laptops (yet).
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
sound/pci/hda/patch_realtek.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 58006c8bcfb9..a690baa202c5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9924,6 +9924,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JI", ALC285_FIXUP_ASUS_HEADSET_MIC),
SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JYR/JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1ccf, "ASUS G814JI", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS ROG Strix G17 2023 (G713PV)", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
--
2.41.0

View File

@ -0,0 +1,64 @@
diff --git a/sound/pci/hda/cd35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index 6b704fd..d63617f 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -6,7 +6,9 @@
//
// Author: Stefan Binding <sbinding@opensource.cirrus.com>
+#include <linux/dmi.h>
#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
#include <linux/string.h>
#include "cs35l41_hda_property.h"
@@ -117,6 +119,40 @@ static int asus_rog_2023_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy
return 0;
}
+static int asus_rog_2023_ally_fix(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
+ const char *hid)
+{
+ const char *rog_ally_bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
+ const char *rog_ally_bios_num = rog_ally_bios_ver + 6; // Dropping the RC71L. part before the number
+ int rog_ally_bios_int;
+ kstrtoint(rog_ally_bios_num, 10, &rog_ally_bios_int);
+ if(rog_ally_bios_int >= 330){
+ printk(KERN_INFO "DSD properties exist in the %d BIOS. Not applying DSD override...\n", rog_ally_bios_int);
+ return -ENOENT; //Patch not applicable. Exiting...
+ }
+
+ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
+
+ dev_info(cs35l41->dev, "Adding DSD properties for %s\n", cs35l41->acpi_subsystem_id);
+
+ cs35l41->index = id == 0x40 ? 0 : 1;
+ cs35l41->channel_index = 0;
+ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
+ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
+ hw_cfg->spk_pos = cs35l41->index;
+ hw_cfg->gpio1.func = CS35L41_NOT_USED;
+ hw_cfg->gpio1.valid = true;
+ hw_cfg->gpio2.func = CS35L41_INTERRUPT;
+ hw_cfg->gpio2.valid = true;
+ hw_cfg->bst_type = CS35L41_INT_BOOST;
+ hw_cfg->bst_ind = 1000; /* 1,000nH Inductance value */
+ hw_cfg->bst_ipk = 4500; /* 4,500mA peak current */
+ hw_cfg->bst_cap = 24; /* 24 microFarad cap value */
+ hw_cfg->valid = true;
+
+ return 0;
+}
+
struct cs35l41_prop_model {
const char *hid;
const char *ssid;
@@ -134,7 +170,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431483", asus_rog_2023_no_acpi }, // GU603V spi, rst=1, spkr=1
{ "CSC3551", "10431493", asus_rog_2023_no_acpi }, // GV601V spi, rst=1
{ "CSC3551", "10431573", asus_rog_2023_no_acpi }, // GZ301V spi, rst=0
- { "CSC3551", "104317F3", asus_rog_2023_no_acpi }, // ROG ALLY i2c, rst=0
+ { "CSC3551", "104317F3", asus_rog_2023_ally_fix }, // ASUS ROG ALLY - i2c, rst=0
{ "CSC3551", "10431B93", asus_rog_2023_no_acpi }, // G614J spi, rst=0
{ "CSC3551", "10431C9F", asus_rog_2023_no_acpi }, // G614JI spi, rst=0
{ "CSC3551", "10431CAF", asus_rog_2023_no_acpi }, // G634J spi, rst=1

View File

@ -0,0 +1,113 @@
From 0a399a37fbe6f6b2b9062e1c076df28608b628c9 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
Date: Fri, 24 Nov 2023 21:13:11 +1300
Subject: [PATCH v2] platform/x86: asus-wmi: disable USB0 hub on ROG Ally
before suspend
ASUS have worked around an issue in XInput where it doesn't support USB
selective suspend, whcih causes suspend issues in Windows. They worked
around this by adjusting the MCU firmware to disable the USB0 hub when
the screen is switched off during the Microsoft DSM suspend path in ACPI.
The issue we have with this however is one of timing - the call the tells
the MCU to this isn't able to complete before suspend is done so we call
this in a prepare() and add a small msleep() to ensure it is done. This
must be done before the screen is switched off to prevent a variety of
possible races.
Without this the MCU is unable to initialise itself correctly on resume.
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
drivers/platform/x86/asus-wmi.c | 40 +++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 6a79f16233ab..563c9ab31bc7 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -16,6 +16,7 @@
#include <linux/acpi.h>
#include <linux/backlight.h>
#include <linux/debugfs.h>
+#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/fb.h>
#include <linux/hwmon.h>
@@ -132,6 +133,9 @@ module_param(fnlock_default, bool, 0444);
#define ASUS_SCREENPAD_BRIGHT_MAX 255
#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"
+
static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
static int throttle_thermal_policy_write(struct asus_wmi *);
@@ -300,6 +304,9 @@ struct asus_wmi {
bool fnlock_locked;
+ /* The ROG Ally device requires the USB hub to be disabled before suspend */
+ bool pre_suspend_ec0_csee_disable;
+
struct asus_wmi_debug debug;
struct asus_wmi_driver *driver;
@@ -4488,6 +4495,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->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->pre_suspend_ec0_csee_disable = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
+ && dmi_match(DMI_BOARD_NAME, "RC71L");
err = fan_boost_mode_check_present(asus);
if (err)
@@ -4654,6 +4663,35 @@ static int asus_hotk_resume(struct device *device)
asus_wmi_fnlock_update(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->pre_suspend_ec0_csee_disable) {
+ /* sleep required to ensure USB0 is enabled before drivers notice */
+ if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8)))
+ pr_warn("ASUS ROG Ally failed to set USB hub power on\n");
+ }
+
+ return 0;
+}
+
+static int asus_hotk_prepare(struct device *device)
+{
+ struct asus_wmi *asus = dev_get_drvdata(device);
+
+ if (asus->pre_suspend_ec0_csee_disable) {
+ /* sleep required to ensure USB0 is disabled before sleep continues */
+ if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7)))
+ pr_warn("ASUS ROG Ally failed to set USB hub power off\n");
+ else
+ msleep(100);
+ }
+
return 0;
}
@@ -4701,6 +4739,8 @@ static const struct dev_pm_ops asus_pm_ops = {
.thaw = asus_hotk_thaw,
.restore = asus_hotk_restore,
.resume = asus_hotk_resume,
+ .resume_early = asus_hotk_resume_early,
+ .prepare = asus_hotk_prepare,
};
/* Registration ***************************************************************/
--
2.43.0

View File

@ -1,77 +1,41 @@
From 7ec1504c16d02fa3f543be2b3bdd6346f353dde0 Mon Sep 17 00:00:00 2001 From b6a7058a13f345d5aa5426466f9104da43d47ce4 Mon Sep 17 00:00:00 2001
From: Peter Jung <admin@ptr1337.dev> From: Piotr Gorski <lucjan.lucjanov@gmail.com>
Date: Sat, 28 Oct 2023 20:49:14 +0200 Date: Tue, 5 Dec 2023 15:49:10 +0100
Subject: [PATCH] bore-cachy Subject: [PATCH] bore-cachy
Signed-off-by: Peter Jung <admin@ptr1337.dev> Signed-off-by: Piotr Gorski <lucjan.lucjanov@gmail.com>
--- ---
include/linux/sched.h | 31 +++++++ include/linux/sched.h | 10 ++
init/Kconfig | 19 ++++ init/Kconfig | 19 ++++
kernel/sched/autogroup.c | 4 + kernel/sched/core.c | 128 ++++++++++++++++++++++++
kernel/sched/core.c | 163 +++++++++++++++++++++++++++++++++ kernel/sched/debug.c | 3 +
kernel/sched/debug.c | 3 + kernel/sched/fair.c | 216 +++++++++++++++++++++++++++++++++++++---
kernel/sched/fair.c | 189 +++++++++++++++++++++++++++++++++++++-- kernel/sched/features.h | 4 +
kernel/sched/features.h | 4 + 6 files changed, 366 insertions(+), 14 deletions(-)
7 files changed, 406 insertions(+), 7 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h diff --git a/include/linux/sched.h b/include/linux/sched.h
index 016610587645..14d0f15160c8 100644 index 77f01ac38..01f2839ad 100644
--- a/include/linux/sched.h --- a/include/linux/sched.h
+++ b/include/linux/sched.h +++ b/include/linux/sched.h
@@ -545,6 +545,24 @@ struct sched_statistics { @@ -559,6 +559,16 @@ struct sched_entity {
#endif /* CONFIG_SCHEDSTATS */
} ____cacheline_aligned;
+#ifdef CONFIG_SCHED_BORE
+typedef union {
+ u16 u16;
+ s16 s16;
+ u8 u8[2];
+ s8 s8[2];
+} x16;
+
+typedef union {
+ u32 u32;
+ s32 s32;
+ u16 u16[2];
+ s16 s16[2];
+ u8 u8[4];
+ s8 s8[4];
+} x32;
+#endif // CONFIG_SCHED_BORE
+
struct sched_entity {
/* For load-balancing: */
struct load_weight load;
@@ -559,6 +577,12 @@ struct sched_entity {
u64 sum_exec_runtime; u64 sum_exec_runtime;
u64 prev_sum_exec_runtime; u64 prev_sum_exec_runtime;
u64 vruntime; u64 vruntime;
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ u64 burst_time; + u64 burst_time;
+ u16 prev_burst_penalty; + u8 prev_burst_penalty;
+ u16 curr_burst_penalty; + u8 curr_burst_penalty;
+ u16 burst_penalty; + u8 burst_penalty;
+ u8 slice_score;
+ u8 child_burst;
+ u16 child_burst_cnt;
+ u64 child_burst_last_cached;
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
s64 vlag; s64 vlag;
u64 slice; u64 slice;
@@ -990,6 +1014,13 @@ struct task_struct {
struct list_head children;
struct list_head sibling;
struct task_struct *group_leader;
+#ifdef CONFIG_SCHED_BORE
+ u16 child_burst_cache;
+ u16 child_burst_count_cache;
+ u64 child_burst_last_cached;
+ u16 group_burst_cache;
+ u64 group_burst_last_cached;
+#endif // CONFIG_SCHED_BORE
/*
* 'ptraced' is the list of tasks this task is using ptrace() on.
diff --git a/init/Kconfig b/init/Kconfig diff --git a/init/Kconfig b/init/Kconfig
index 9dee4c100348..6e5c69185d62 100644 index 9dee4c100..49d343e97 100644
--- a/init/Kconfig --- a/init/Kconfig
+++ b/init/Kconfig +++ b/init/Kconfig
@@ -1278,6 +1278,25 @@ config CHECKPOINT_RESTORE @@ -1278,6 +1278,25 @@ config CHECKPOINT_RESTORE
@ -95,60 +59,38 @@ index 9dee4c100348..6e5c69185d62 100644
+ +
+ You can turn it off by setting the sysctl kernel.sched_bore = 0. + You can turn it off by setting the sysctl kernel.sched_bore = 0.
+ +
+ If unsure say Y here. + If unsure, say Y here.
+ +
config SCHED_AUTOGROUP config SCHED_AUTOGROUP
bool "Automatic process group scheduling" bool "Automatic process group scheduling"
select CGROUPS select CGROUPS
diff --git a/kernel/sched/autogroup.c b/kernel/sched/autogroup.c
index 991fc9002535..fdeb3401730c 100644
--- a/kernel/sched/autogroup.c
+++ b/kernel/sched/autogroup.c
@@ -4,7 +4,11 @@
* Auto-group scheduling implementation:
*/
+#ifdef CONFIG_SCHED_BORE
+unsigned int __read_mostly sysctl_sched_autogroup_enabled = 0;
+#else // CONFIG_SCHED_BORE
unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
+#endif // CONFIG_SCHED_BORE
static struct autogroup autogroup_default;
static atomic_t autogroup_seq_nr;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 6d72bb67e84f..b08003611d28 100644 index a854b7183..a98cfa7ab 100644
--- a/kernel/sched/core.c --- a/kernel/sched/core.c
+++ b/kernel/sched/core.c +++ b/kernel/sched/core.c
@@ -4490,6 +4490,158 @@ int wake_up_state(struct task_struct *p, unsigned int state) @@ -4488,6 +4488,123 @@ int wake_up_state(struct task_struct *p, unsigned int state)
return try_to_wake_up(p, state, 0); return try_to_wake_up(p, state, 0);
} }
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+extern unsigned int sched_burst_cache_lifetime; +extern bool sched_bore;
+extern unsigned int sched_bore; +extern u8 sched_burst_fork_atavistic;
+extern unsigned int sched_burst_fork_atavistic; +extern uint sched_burst_cache_lifetime;
+ +
+void __init sched_init_bore(void) { +void __init sched_init_bore(void) {
+ init_task.child_burst_cache = 0;
+ init_task.child_burst_count_cache = 0;
+ init_task.child_burst_last_cached = 0;
+ init_task.group_burst_cache = 0;
+ init_task.group_burst_last_cached = 0;
+ init_task.se.burst_time = 0; + init_task.se.burst_time = 0;
+ init_task.se.prev_burst_penalty = 0; + init_task.se.prev_burst_penalty = 0;
+ init_task.se.curr_burst_penalty = 0; + init_task.se.curr_burst_penalty = 0;
+ init_task.se.burst_penalty = 0; + init_task.se.burst_penalty = 0;
+ init_task.se.slice_score = 0;
+ init_task.se.child_burst_last_cached = 0;
+} +}
+ +
+void inline sched_fork_bore(struct task_struct *p) { +void inline sched_fork_bore(struct task_struct *p) {
+ p->child_burst_cache = 0;
+ p->child_burst_count_cache = 0;
+ p->child_burst_last_cached = 0;
+ p->group_burst_cache = 0;
+ p->group_burst_last_cached = 0;
+ p->se.burst_time = 0; + p->se.burst_time = 0;
+ p->se.curr_burst_penalty = 0; + p->se.curr_burst_penalty = 0;
+ p->se.slice_score = 0;
+ p->se.child_burst_last_cached = 0;
+} +}
+ +
+static u32 count_child_tasks(struct task_struct *p) { +static u32 count_child_tasks(struct task_struct *p) {
@ -159,20 +101,16 @@ index 6d72bb67e84f..b08003611d28 100644
+} +}
+ +
+static inline bool child_burst_cache_expired(struct task_struct *p, u64 now) { +static inline bool child_burst_cache_expired(struct task_struct *p, u64 now) {
+ return (p->child_burst_last_cached + sched_burst_cache_lifetime < now); + return (p->se.child_burst_last_cached + sched_burst_cache_lifetime < now);
+}
+
+static inline bool group_burst_cache_expired(struct task_struct *p, u64 now) {
+ return (p->group_burst_last_cached + sched_burst_cache_lifetime < now);
+} +}
+ +
+static void __update_child_burst_cache( +static void __update_child_burst_cache(
+ struct task_struct *p, u32 cnt, u32 sum, u64 now) { + struct task_struct *p, u32 cnt, u32 sum, u64 now) {
+ u16 avg = 0; + u8 avg = 0;
+ if (cnt) avg = sum / cnt; + if (cnt) avg = sum / cnt;
+ p->child_burst_cache = max(avg, p->se.burst_penalty); + p->se.child_burst = max(avg, p->se.burst_penalty);
+ p->child_burst_count_cache = cnt; + p->se.child_burst_cnt = cnt;
+ p->child_burst_last_cached = now; + p->se.child_burst_last_cached = now;
+} +}
+ +
+static void update_child_burst_cache(struct task_struct *p, u64 now) { +static void update_child_burst_cache(struct task_struct *p, u64 now) {
@ -181,6 +119,7 @@ index 6d72bb67e84f..b08003611d28 100644
+ u32 sum = 0; + u32 sum = 0;
+ +
+ list_for_each_entry(child, &p->children, sibling) { + list_for_each_entry(child, &p->children, sibling) {
+ if (child->sched_class != &fair_sched_class) continue;
+ cnt++; + cnt++;
+ sum += child->se.burst_penalty; + sum += child->se.burst_penalty;
+ } + }
@ -200,16 +139,17 @@ index 6d72bb67e84f..b08003611d28 100644
+ dec = list_first_entry(&dec->children, struct task_struct, sibling); + dec = list_first_entry(&dec->children, struct task_struct, sibling);
+ +
+ if (!dcnt || !depth) { + if (!dcnt || !depth) {
+ if (dec->sched_class != &fair_sched_class) continue;
+ cnt++; + cnt++;
+ sum += dec->se.burst_penalty; + sum += dec->se.burst_penalty;
+ } else { + continue;
+ if (child_burst_cache_expired(dec, now))
+ update_child_burst_cache_atavistic(dec, now, depth - 1, &cnt, &sum);
+ else {
+ cnt += dec->child_burst_count_cache;
+ sum += (u32)dec->child_burst_cache * dec->child_burst_count_cache;
+ }
+ } + }
+ if (!child_burst_cache_expired(dec, now)) {
+ cnt += dec->se.child_burst_cnt;
+ sum += (u32)dec->se.child_burst * dec->se.child_burst_cnt;
+ continue;
+ }
+ update_child_burst_cache_atavistic(dec, now, depth - 1, &cnt, &sum);
+ } + }
+ +
+ __update_child_burst_cache(p, cnt, sum, now); + __update_child_burst_cache(p, cnt, sum, now);
@ -217,57 +157,30 @@ index 6d72bb67e84f..b08003611d28 100644
+ *asum += sum; + *asum += sum;
+} +}
+ +
+static void update_group_burst_cache(struct task_struct *p, u64 now) { +static void sched_post_fork_bore(struct task_struct *p) {
+ struct task_struct *member;
+ u32 cnt = 0, sum = 0;
+ u16 avg = 0;
+
+ for_each_thread(p, member) {
+ cnt++;
+ sum += member->se.burst_penalty;
+ }
+
+ if (cnt) avg = sum / cnt;
+ p->group_burst_cache = max(avg, p->se.burst_penalty);
+ p->group_burst_last_cached = now;
+}
+
+#define forked_task_is_process(p) (p->pid == p->tgid)
+#define bore_thread_fork_group_inherit (sched_burst_fork_atavistic & 4)
+
+static void fork_burst_penalty(struct task_struct *p) {
+ struct sched_entity *se = &p->se; + struct sched_entity *se = &p->se;
+ struct task_struct *anc; + struct task_struct *anc;
+ u64 now = ktime_get_ns(); + u64 now;
+ u32 cnt = 0, sum = 0, depth; + u32 cnt = 0, sum = 0, depth;
+ u16 burst_cache; + u8 burst_cache;
+ +
+ if (likely(sched_bore)) { + if (likely(sched_bore)) {
+ now = ktime_get_ns();
+ read_lock(&tasklist_lock); + read_lock(&tasklist_lock);
+ +
+ if (forked_task_is_process(p) || + anc = p->real_parent;
+ likely(!bore_thread_fork_group_inherit)) { + depth = sched_burst_fork_atavistic;
+ anc = p->real_parent; + if (likely(depth)) {
+ depth = sched_burst_fork_atavistic & 3; + while ((anc->real_parent != anc) && (count_child_tasks(anc) == 1))
+ if (likely(depth)) { + anc = anc->real_parent;
+ while ((anc->real_parent != anc) && + if (child_burst_cache_expired(anc, now))
+ (count_child_tasks(anc) == 1)) + update_child_burst_cache_atavistic(
+ anc = anc->real_parent; + anc, now, depth - 1, &cnt, &sum);
+ if (child_burst_cache_expired(anc, now)) + } else
+ update_child_burst_cache_atavistic( + if (child_burst_cache_expired(anc, now))
+ anc, now, depth - 1, &cnt, &sum); + update_child_burst_cache(anc, now);
+ } else
+ if (child_burst_cache_expired(anc, now))
+ update_child_burst_cache(anc, now);
+ +
+ burst_cache = anc->child_burst_cache; + burst_cache = anc->se.child_burst;
+ } else {
+ anc = p->group_leader;
+ if (group_burst_cache_expired(anc, now))
+ update_group_burst_cache(anc, now);
+
+ burst_cache = anc->group_burst_cache;
+ }
+ +
+ read_unlock(&tasklist_lock); + read_unlock(&tasklist_lock);
+ se->prev_burst_penalty = max(se->prev_burst_penalty, burst_cache); + se->prev_burst_penalty = max(se->prev_burst_penalty, burst_cache);
@ -279,7 +192,7 @@ index 6d72bb67e84f..b08003611d28 100644
/* /*
* Perform scheduler related setup for a newly forked process p. * Perform scheduler related setup for a newly forked process p.
* p is forked by current. * p is forked by current.
@@ -4506,6 +4658,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) @@ -4504,6 +4621,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
p->se.prev_sum_exec_runtime = 0; p->se.prev_sum_exec_runtime = 0;
p->se.nr_migrations = 0; p->se.nr_migrations = 0;
p->se.vruntime = 0; p->se.vruntime = 0;
@ -287,32 +200,32 @@ index 6d72bb67e84f..b08003611d28 100644
+ sched_fork_bore(p); + sched_fork_bore(p);
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
p->se.vlag = 0; p->se.vlag = 0;
p->se.slice = sysctl_sched_base_slice;
INIT_LIST_HEAD(&p->se.group_node); INIT_LIST_HEAD(&p->se.group_node);
@@ -4823,6 +4943,9 @@ void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs)
@@ -4827,6 +4982,9 @@ void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs)
void sched_post_fork(struct task_struct *p) void sched_post_fork(struct task_struct *p)
{ {
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ fork_burst_penalty(p); + sched_post_fork_bore(p);
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
uclamp_post_fork(p); uclamp_post_fork(p);
} }
@@ -9950,6 +10108,11 @@ void __init sched_init(void) @@ -9922,6 +10045,11 @@ void __init sched_init(void)
BUG_ON(&dl_sched_class != &stop_sched_class + 1); BUG_ON(&dl_sched_class != &stop_sched_class + 1);
#endif #endif
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ sched_init_bore(); + sched_init_bore();
+ printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification 3.2.9 by Masahito Suzuki"); + printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification 3.5.7 by Masahito Suzuki");
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
+ +
wait_bit_init(); wait_bit_init();
#ifdef CONFIG_FAIR_GROUP_SCHED #ifdef CONFIG_FAIR_GROUP_SCHED
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 5c743bcb340d..d427b1e6b415 100644 index 4c3d0d9f3..e37fdfad1 100644
--- a/kernel/sched/debug.c --- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c +++ b/kernel/sched/debug.c
@@ -595,6 +595,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p) @@ -595,6 +595,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
@ -320,13 +233,13 @@ index 5c743bcb340d..d427b1e6b415 100644
SPLIT_NS(schedstat_val_or_zero(p->stats.sum_block_runtime))); SPLIT_NS(schedstat_val_or_zero(p->stats.sum_block_runtime)));
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ SEQ_printf(m, " %2d", ((x16*)&p->se.burst_penalty)->u8[1]); + SEQ_printf(m, " %2d", p->se.slice_score);
+#endif +#endif
#ifdef CONFIG_NUMA_BALANCING #ifdef CONFIG_NUMA_BALANCING
SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p)); SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p));
#endif #endif
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index fd2fe1131d40..7a0e3a92c999 100644 index fa9fff0f9..5e4f0ccff 100644
--- a/kernel/sched/fair.c --- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c +++ b/kernel/sched/fair.c
@@ -19,6 +19,9 @@ @@ -19,6 +19,9 @@
@ -370,32 +283,29 @@ index fd2fe1131d40..7a0e3a92c999 100644
/* /*
* After fork, child runs first. If set to 0 (default) then * After fork, child runs first. If set to 0 (default) then
@@ -86,6 +100,66 @@ unsigned int sysctl_sched_child_runs_first __read_mostly; @@ -86,6 +100,68 @@ unsigned int sysctl_sched_child_runs_first __read_mostly;
const_debug unsigned int sysctl_sched_migration_cost = 500000UL; const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+unsigned int __read_mostly sched_bore = 1; +bool __read_mostly sched_bore = 1;
+unsigned int __read_mostly sched_burst_cache_lifetime = 60000000; +bool __read_mostly sched_burst_score_rounding = 0;
+unsigned int __read_mostly sched_burst_penalty_offset = 22; +bool __read_mostly sched_burst_smoothness_long = 1;
+unsigned int __read_mostly sched_burst_penalty_scale = 1280; +bool __read_mostly sched_burst_smoothness_short = 0;
+unsigned int __read_mostly sched_burst_smoothness_up = 1; +u8 __read_mostly sched_burst_fork_atavistic = 2;
+unsigned int __read_mostly sched_burst_smoothness_down = 0; +u8 __read_mostly sched_burst_penalty_offset = 22;
+unsigned int __read_mostly sched_burst_fork_atavistic = 2; +uint __read_mostly sched_burst_penalty_scale = 1280;
+static int three = 3; +uint __read_mostly sched_burst_cache_lifetime = 60000000;
+static int seven = 7; +static u8 sixty_four = 64;
+static int sixty_four = 64; +static uint maxval_12_bits = 4095;
+static int maxval_12_bits = 4095;
+ +
+#define MAX_BURST_PENALTY ((40U << 8) - 1) +#define MAX_BURST_PENALTY (39U <<2)
+ +
+static inline u32 log2plus1_u64_u32f8(u64 v) { +static inline u32 log2plus1_u64_u32f8(u64 v) {
+ x32 result; + u32 msb = fls64(v);
+ int msb = fls64(v); + s32 excess_bits = msb - 9;
+ int excess_bits = msb - 9; + u8 fractional = (0 <= excess_bits)? v >> excess_bits: v << -excess_bits;
+ result.u8[0] = (0 <= excess_bits)? v >> excess_bits: v << -excess_bits; + return msb << 8 | fractional;
+ result.u8[1] = msb;
+ return result.u32;
+} +}
+ +
+static inline u32 calc_burst_penalty(u64 burst_time) { +static inline u32 calc_burst_penalty(u64 burst_time) {
@ -404,26 +314,31 @@ index fd2fe1131d40..7a0e3a92c999 100644
+ greed = log2plus1_u64_u32f8(burst_time); + greed = log2plus1_u64_u32f8(burst_time);
+ tolerance = sched_burst_penalty_offset << 8; + tolerance = sched_burst_penalty_offset << 8;
+ penalty = max(0, (s32)greed - (s32)tolerance); + penalty = max(0, (s32)greed - (s32)tolerance);
+ scaled_penalty = penalty * sched_burst_penalty_scale >> 10; + scaled_penalty = penalty * sched_burst_penalty_scale >> 16;
+ +
+ return min(MAX_BURST_PENALTY, scaled_penalty); + return min(MAX_BURST_PENALTY, scaled_penalty);
+} +}
+ +
+static void update_burst_penalty(struct sched_entity *se) { +static inline void update_burst_penalty(struct sched_entity *se) {
+ se->curr_burst_penalty = calc_burst_penalty(se->burst_time); + se->curr_burst_penalty = calc_burst_penalty(se->burst_time);
+ se->burst_penalty = max(se->prev_burst_penalty, se->curr_burst_penalty); + se->burst_penalty = max(se->prev_burst_penalty, se->curr_burst_penalty);
+} +}
+ +
+static inline u64 penalty_scale(u64 delta, struct sched_entity *se) { +static inline void update_slice_score(struct sched_entity *se) {
+ u32 score = ((x16*)&se->burst_penalty)->u8[1]; + u32 penalty = se->burst_penalty;
+ return mul_u64_u32_shr(delta, sched_prio_to_wmult[score], 22); + if (sched_burst_score_rounding) penalty += 0x2U;
+ se->slice_score = penalty >> 2;
+}
+
+static inline u64 scale_slice(u64 delta, struct sched_entity *se) {
+ return mul_u64_u32_shr(delta, sched_prio_to_wmult[se->slice_score], 22);
+} +}
+ +
+static inline u32 binary_smooth(u32 new, u32 old) { +static inline u32 binary_smooth(u32 new, u32 old) {
+ int increment = new - old; + int increment = new - old;
+ return (0 <= increment)? + return (0 <= increment)?
+ old + ( increment >> sched_burst_smoothness_up): + old + ( increment >> (int)sched_burst_smoothness_long):
+ old - (-increment >> sched_burst_smoothness_down); + old - (-increment >> (int)sched_burst_smoothness_short);
+} +}
+ +
+static void restart_burst(struct sched_entity *se) { +static void restart_burst(struct sched_entity *se) {
@ -437,7 +352,7 @@ index fd2fe1131d40..7a0e3a92c999 100644
int sched_thermal_decay_shift; int sched_thermal_decay_shift;
static int __init setup_sched_thermal_decay_shift(char *str) static int __init setup_sched_thermal_decay_shift(char *str)
{ {
@@ -145,6 +219,69 @@ static unsigned int sysctl_numa_balancing_promote_rate_limit = 65536; @@ -145,6 +221,70 @@ static unsigned int sysctl_numa_balancing_promote_rate_limit = 65536;
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static struct ctl_table sched_fair_sysctls[] = { static struct ctl_table sched_fair_sysctls[] = {
@ -445,79 +360,80 @@ index fd2fe1131d40..7a0e3a92c999 100644
+ { + {
+ .procname = "sched_bore", + .procname = "sched_bore",
+ .data = &sched_bore, + .data = &sched_bore,
+ .maxlen = sizeof(unsigned int), + .maxlen = sizeof(bool),
+ .mode = 0644, + .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax, + .proc_handler = &proc_dobool,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ }, + },
+ { + {
+ .procname = "sched_burst_cache_lifetime", + .procname = "sched_burst_cache_lifetime",
+ .data = &sched_burst_cache_lifetime, + .data = &sched_burst_cache_lifetime,
+ .maxlen = sizeof(unsigned int), + .maxlen = sizeof(uint),
+ .mode = 0644, + .mode = 0644,
+ .proc_handler = proc_dointvec, + .proc_handler = proc_douintvec,
+ }, + },
+ { + {
+ .procname = "sched_burst_fork_atavistic", + .procname = "sched_burst_fork_atavistic",
+ .data = &sched_burst_fork_atavistic, + .data = &sched_burst_fork_atavistic,
+ .maxlen = sizeof(unsigned int), + .maxlen = sizeof(u8),
+ .mode = 0644, + .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax, + .proc_handler = &proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO, + .extra1 = SYSCTL_ZERO,
+ .extra2 = &seven, + .extra2 = SYSCTL_THREE,
+ }, + },
+ { + {
+ .procname = "sched_burst_penalty_offset", + .procname = "sched_burst_penalty_offset",
+ .data = &sched_burst_penalty_offset, + .data = &sched_burst_penalty_offset,
+ .maxlen = sizeof(unsigned int), + .maxlen = sizeof(u8),
+ .mode = 0644, + .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax, + .proc_handler = &proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO, + .extra1 = SYSCTL_ZERO,
+ .extra2 = &sixty_four, + .extra2 = &sixty_four,
+ }, + },
+ { + {
+ .procname = "sched_burst_penalty_scale", + .procname = "sched_burst_penalty_scale",
+ .data = &sched_burst_penalty_scale, + .data = &sched_burst_penalty_scale,
+ .maxlen = sizeof(unsigned int), + .maxlen = sizeof(uint),
+ .mode = 0644, + .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax, + .proc_handler = &proc_douintvec_minmax,
+ .extra1 = SYSCTL_ZERO, + .extra1 = SYSCTL_ZERO,
+ .extra2 = &maxval_12_bits, + .extra2 = &maxval_12_bits,
+ }, + },
+ { + {
+ .procname = "sched_burst_smoothness_down", + .procname = "sched_burst_score_rounding",
+ .data = &sched_burst_smoothness_down, + .data = &sched_burst_score_rounding,
+ .maxlen = sizeof(unsigned int), + .maxlen = sizeof(bool),
+ .mode = 0644, + .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax, + .proc_handler = &proc_dobool,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = &three,
+ }, + },
+ { + {
+ .procname = "sched_burst_smoothness_up", + .procname = "sched_burst_smoothness_long",
+ .data = &sched_burst_smoothness_up, + .data = &sched_burst_smoothness_long,
+ .maxlen = sizeof(unsigned int), + .maxlen = sizeof(bool),
+ .mode = 0644, + .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax, + .proc_handler = &proc_dobool,
+ .extra1 = SYSCTL_ZERO, + },
+ .extra2 = &three, + {
+ .procname = "sched_burst_smoothness_short",
+ .data = &sched_burst_smoothness_short,
+ .maxlen = sizeof(bool),
+ .mode = 0644,
+ .proc_handler = &proc_dobool,
+ }, + },
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
{ {
.procname = "sched_child_runs_first", .procname = "sched_child_runs_first",
.data = &sysctl_sched_child_runs_first, .data = &sysctl_sched_child_runs_first,
@@ -313,6 +450,9 @@ static inline u64 calc_delta_fair(u64 delta, struct sched_entity *se) @@ -313,6 +453,9 @@ static inline u64 calc_delta_fair(u64 delta, struct sched_entity *se)
if (unlikely(se->load.weight != NICE_0_LOAD)) if (unlikely(se->load.weight != NICE_0_LOAD))
delta = __calc_delta(delta, NICE_0_LOAD, &se->load); delta = __calc_delta(delta, NICE_0_LOAD, &se->load);
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ if (likely(sched_bore)) delta = penalty_scale(delta, se); + if (likely(sched_bore)) delta = scale_slice(delta, se);
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
return delta; return delta;
} }
@@ -668,7 +808,7 @@ void avg_vruntime_update(struct cfs_rq *cfs_rq, s64 delta) @@ -668,7 +811,7 @@ void avg_vruntime_update(struct cfs_rq *cfs_rq, s64 delta)
* Specifically: avg_runtime() + 0 must result in entity_eligible() := true * Specifically: avg_runtime() + 0 must result in entity_eligible() := true
* For this to be so, the result of this function must have a left bias. * For this to be so, the result of this function must have a left bias.
*/ */
@ -526,7 +442,7 @@ index fd2fe1131d40..7a0e3a92c999 100644
{ {
struct sched_entity *curr = cfs_rq->curr; struct sched_entity *curr = cfs_rq->curr;
s64 avg = cfs_rq->avg_vruntime; s64 avg = cfs_rq->avg_vruntime;
@@ -688,7 +828,11 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq) @@ -688,7 +831,11 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq)
avg = div_s64(avg, load); avg = div_s64(avg, load);
} }
@ -539,7 +455,22 @@ index fd2fe1131d40..7a0e3a92c999 100644
} }
/* /*
@@ -981,7 +1125,6 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq) @@ -709,13 +856,8 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq)
*/
static void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
- s64 lag, limit;
-
SCHED_WARN_ON(!se->on_rq);
- lag = avg_vruntime(cfs_rq) - se->vruntime;
-
- limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se);
- se->vlag = clamp(lag, -limit, limit);
+ se->vlag = avg_vruntime(cfs_rq) - se->vruntime;
}
/*
@@ -981,7 +1123,6 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq)
return se; return se;
} }
@ -547,7 +478,7 @@ index fd2fe1131d40..7a0e3a92c999 100644
struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
{ {
struct rb_node *last = rb_last(&cfs_rq->tasks_timeline.rb_root); struct rb_node *last = rb_last(&cfs_rq->tasks_timeline.rb_root);
@@ -995,6 +1138,7 @@ struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) @@ -995,6 +1136,7 @@ struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
/************************************************************** /**************************************************************
* Scheduling class statistics methods: * Scheduling class statistics methods:
*/ */
@ -555,7 +486,17 @@ index fd2fe1131d40..7a0e3a92c999 100644
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
int sched_update_scaling(void) int sched_update_scaling(void)
{ {
@@ -1181,7 +1325,11 @@ static void update_curr(struct cfs_rq *cfs_rq) @@ -1031,6 +1173,9 @@ static void update_deadline(struct cfs_rq *cfs_rq, struct sched_entity *se)
/*
* EEVDF: vd_i = ve_i + r_i / w_i
*/
+#ifdef CONFIG_SCHED_BORE
+ update_slice_score(se);
+#endif // CONFIG_SCHED_BORE
se->deadline = se->vruntime + calc_delta_fair(se->slice, se);
/*
@@ -1173,7 +1318,11 @@ static void update_curr(struct cfs_rq *cfs_rq)
curr->sum_exec_runtime += delta_exec; curr->sum_exec_runtime += delta_exec;
schedstat_add(cfs_rq->exec_clock, delta_exec); schedstat_add(cfs_rq->exec_clock, delta_exec);
@ -568,21 +509,44 @@ index fd2fe1131d40..7a0e3a92c999 100644
update_deadline(cfs_rq, curr); update_deadline(cfs_rq, curr);
update_min_vruntime(cfs_rq); update_min_vruntime(cfs_rq);
@@ -5061,6 +5209,23 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) @@ -5066,6 +5215,9 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
s64 lag = 0;
se->slice = sysctl_sched_base_slice;
+#ifdef CONFIG_SCHED_BORE
+ update_slice_score(se);
+#endif // CONFIG_SCHED_BORE
vslice = calc_delta_fair(se->slice, se);
/*
@@ -5080,7 +5232,13 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
struct sched_entity *curr = cfs_rq->curr;
unsigned long load;
- lag = se->vlag;
+ u64 slice = se->slice;
+#ifdef CONFIG_SCHED_BORE
+ if (unlikely(!sched_bore))
+#endif // CONFIG_SCHED_BORE
+ slice *= 2;
+ s64 limit = calc_delta_fair(max_t(u64, slice, TICK_NSEC), se);
+ lag = clamp(se->vlag, -limit, limit);
/*
* If we want to place a task and preserve lag, we have to
@@ -5142,6 +5300,21 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
if (WARN_ON_ONCE(!load)) if (WARN_ON_ONCE(!load))
load = 1; load = 1;
lag = div_s64(lag, load); lag = div_s64(lag, load);
+ +
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ if (flags & ENQUEUE_MIGRATED && likely(sched_bore)) { + if (flags & ENQUEUE_MIGRATED && likely(sched_bore)) {
+ struct sched_entity *last, *first;
+ s64 left_vruntime = vruntime, right_vruntime = vruntime; + s64 left_vruntime = vruntime, right_vruntime = vruntime;
+ struct sched_entity *first = __pick_first_entity(cfs_rq),
+ *last = __pick_last_entity(cfs_rq);
+ +
+ if (first = __pick_first_entity(cfs_rq)) + if (first) left_vruntime = first->vruntime;
+ left_vruntime = first->vruntime; + if (last) right_vruntime = last->vruntime;
+
+ if (last = __pick_last_entity(cfs_rq))
+ right_vruntime = last->vruntime;
+ +
+ lag = clamp(lag, + lag = clamp(lag,
+ (s64)vruntime - right_vruntime, + (s64)vruntime - right_vruntime,
@ -592,17 +556,20 @@ index fd2fe1131d40..7a0e3a92c999 100644
} }
se->vruntime = vruntime - lag; se->vruntime = vruntime - lag;
@@ -6619,6 +6784,9 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) @@ -6698,6 +6871,12 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
bool was_sched_idle = sched_idle_rq(rq);
util_est_dequeue(&rq->cfs, p); util_est_dequeue(&rq->cfs, p);
+#ifdef CONFIG_SCHED_BORE
+ if (task_sleep) {
+ update_curr(cfs_rq_of(se));
+ restart_burst(se);
+ }
+#endif // CONFIG_SCHED_BORE
for_each_sched_entity(se) { for_each_sched_entity(se) {
+#ifdef CONFIG_SCHED_BORE
+ if (task_sleep) restart_burst(se);
+#endif // CONFIG_SCHED_BORE
cfs_rq = cfs_rq_of(se); cfs_rq = cfs_rq_of(se);
dequeue_entity(cfs_rq, se, flags); @@ -8429,8 +8608,13 @@ static void yield_task_fair(struct rq *rq)
@@ -8349,8 +8517,12 @@ static void yield_task_fair(struct rq *rq)
/* /*
* Are we the only task in the tree? * Are we the only task in the tree?
*/ */
@ -610,24 +577,26 @@ index fd2fe1131d40..7a0e3a92c999 100644
+ if (unlikely(rq->nr_running == 1)) { + if (unlikely(rq->nr_running == 1)) {
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ restart_burst(se); + restart_burst(se);
+ update_slice_score(se);
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
return; return;
+ } + }
clear_buddies(cfs_rq, se); clear_buddies(cfs_rq, se);
@@ -8359,6 +8531,9 @@ static void yield_task_fair(struct rq *rq) @@ -8439,6 +8623,10 @@ static void yield_task_fair(struct rq *rq)
* Update run-time statistics of the 'current'. * Update run-time statistics of the 'current'.
*/ */
update_curr(cfs_rq); update_curr(cfs_rq);
+#ifdef CONFIG_SCHED_BORE +#ifdef CONFIG_SCHED_BORE
+ restart_burst(se); + restart_burst(se);
+ update_slice_score(se);
+#endif // CONFIG_SCHED_BORE +#endif // CONFIG_SCHED_BORE
/* /*
* Tell update_rq_clock() that we've just updated, * Tell update_rq_clock() that we've just updated,
* so we don't do microscopic update in schedule() * so we don't do microscopic update in schedule()
diff --git a/kernel/sched/features.h b/kernel/sched/features.h diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index f770168230ae..a2e09c04f3cb 100644 index f77016823..a2e09c04f 100644
--- a/kernel/sched/features.h --- a/kernel/sched/features.h
+++ b/kernel/sched/features.h +++ b/kernel/sched/features.h
@@ -6,7 +6,11 @@ @@ -6,7 +6,11 @@
@ -643,4 +612,5 @@ index f770168230ae..a2e09c04f3cb 100644
/* /*
* Prefer to schedule the task we woke last (assuming it failed * Prefer to schedule the task we woke last (assuming it failed
-- --
2.42.0 2.43.0.rc2

File diff suppressed because it is too large Load Diff

View File

@ -10,25 +10,25 @@ This reverts commit 907830b0fc9e374d00f3c83de5e426157b482c01.
1 file changed, 1 insertion(+), 8 deletions(-) 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 3f353572588d..1c8cc4b98f95 100644 index a607f277c..3174fa871 100644
--- a/drivers/pci/pci.c --- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c +++ b/drivers/pci/pci.c
@@ -3637,14 +3637,7 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) @@ -3755,14 +3755,8 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
return 0; return 0;
pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
- cap &= PCI_REBAR_CAP_SIZES; - cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap);
-
- /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ - /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
- if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && - if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
- bar == 0 && cap == 0x7000) - bar == 0 && cap == 0x700)
- cap = 0x3f000; - return 0x3f00;
- -
- return cap >> 4; - return cap;
+ return (cap & PCI_REBAR_CAP_SIZES) >> 4; + return (cap & PCI_REBAR_CAP_SIZES) >> 4;
} }
EXPORT_SYMBOL(pci_rebar_get_possible_sizes); EXPORT_SYMBOL(pci_rebar_get_possible_sizes);
-- --
2.30.2 2.30.2

View File

@ -4,7 +4,11 @@ Date: Mon, 30 Oct 2023 22:36:19 -0600
Subject: [PATCH] Revert "nvme-pci: drop redundant Subject: [PATCH] Revert "nvme-pci: drop redundant
pci_enable_pcie_error_reporting()" pci_enable_pcie_error_reporting()"
This reverts commit 1ad11eafc63ac16e667853bee4273879226d2d1b. This reverts commits:
1ad11eafc63ac16e667853bee4273879226d2d1b
7ec4b34be4234599cf1241ef807cdb7c3636f6fe
69b264df8a412820e98867dbab871c6526c5e5aa
--- ---
drivers/nvme/host/pci.c | 6 +++++- drivers/nvme/host/pci.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-) 1 file changed, 5 insertions(+), 1 deletion(-)
@ -43,4 +47,62 @@ index 3f0c9ee09a12..bc11bfe6f87a 100644
nvme_cancel_tagset(&dev->ctrl); nvme_cancel_tagset(&dev->ctrl);
-- --
2.41.0 2.41.0
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 29cc10220..94ce49a5f 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -41,9 +41,20 @@ struct aer_capability_regs {
};
#if defined(CONFIG_PCIEAER)
+/* PCIe port driver needs this function to enable AER */
+int pci_enable_pcie_error_reporting(struct pci_dev *dev);
+int pci_disable_pcie_error_reporting(struct pci_dev *dev);
int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
int pcie_aer_is_native(struct pci_dev *dev);
#else
+static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
+{
+ return -EINVAL;
+}
+static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev)
+{
+ return -EINVAL;
+}
static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{
return -EINVAL;
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index 9c8fd69ae..0dc7be481 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -231,7 +231,7 @@ int pcie_aer_is_native(struct pci_dev *dev)
}
EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, CXL);
-static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
+int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
int rc;
@@ -241,6 +241,19 @@ static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
rc = pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
return pcibios_err_to_errno(rc);
}
+EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
+
+int pci_disable_pcie_error_reporting(struct pci_dev *dev)
+{
+ int rc;
+
+ if (!pcie_aer_is_native(dev))
+ return -EIO;
+
+ rc = pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
+ return pcibios_err_to_errno(rc);
+}
+EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{

View File

@ -0,0 +1,25 @@
From 9179080ffaaf1d438db6e0a5a37bdf8dafe233a6 Mon Sep 17 00:00:00 2001
From: Thomas Crider <gloriouseggroll@gmail.com>
Date: Mon, 27 Nov 2023 16:13:13 -0500
Subject: [PATCH] Set amdgpu.ppfeaturemask=0xffffffff as default
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index e06009966..4e791eb8f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -158,7 +158,7 @@ bool enforce_isolation;
* OverDrive(bit 14) disabled by default
* GFX DCS(bit 19) disabled by default
*/
-uint amdgpu_pp_feature_mask = 0xfff7bfff;
+uint amdgpu_pp_feature_mask = 0xffffffff;
uint amdgpu_force_long_training;
int amdgpu_lbpw = -1;
int amdgpu_compute_multipipe = -1;
--
2.43.0

View File

@ -0,0 +1,506 @@
From 3f14226e2e90dba5d72c106da29e1876eb7b88ff Mon Sep 17 00:00:00 2001
From: Denis <benato.denis96@gmail.com>
Date: Thu, 28 Sep 2023 03:40:53 +0200
Subject: [PATCH] add acpi_call
---
drivers/platform/x86/Kconfig | 5 +
drivers/platform/x86/Makefile | 4 +
drivers/platform/x86/acpi_call.c | 449 +++++++++++++++++++++++++++++++
3 files changed, 458 insertions(+)
create mode 100644 drivers/platform/x86/acpi_call.c
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 49c2c4cd8d00..fde791e51261 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -170,6 +170,11 @@ config ACER_WIRELESS
If you choose to compile this driver as a module the module will be
called acer-wireless.
+config ACPI_CALL
+ tristate "acpi_call module"
+ help
+ This embeds acpi_call module into the kernel
+
config ACER_WMI
tristate "Acer WMI Laptop Extras"
depends on BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 52dfdf574ac2..1e434fcb8273 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -4,10 +4,14 @@
# x86 Platform-Specific Drivers
#
+# ACPI calls
+
# Windows Management Interface
obj-$(CONFIG_ACPI_WMI) += wmi.o
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
+obj-$(CONFIG_ACPI_CALL) += acpi_call.o
+
# WMI drivers
obj-$(CONFIG_HUAWEI_WMI) += huawei-wmi.o
obj-$(CONFIG_MXM_WMI) += mxm-wmi.o
diff --git a/drivers/platform/x86/acpi_call.c b/drivers/platform/x86/acpi_call.c
new file mode 100644
index 000000000000..d7bc238e16da
--- /dev/null
+++ b/drivers/platform/x86/acpi_call.c
@@ -0,0 +1,449 @@
+/* Copyright (c) 2010: Michal Kottman */
+
+#define BUILDING_ACPICA
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
+#include <asm/uaccess.h>
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+#include <linux/acpi.h>
+#else
+#include <acpi/acpi.h>
+#endif
+
+MODULE_LICENSE("GPL");
+
+/* Uncomment the following line to enable debug messages */
+/*
+#define DEBUG
+*/
+
+#define BUFFER_SIZE 4096
+#define INPUT_BUFFER_SIZE (2 * BUFFER_SIZE)
+#define MAX_ACPI_ARGS 16
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#define HAVE_PROC_CREATE
+#endif
+
+extern struct proc_dir_entry *acpi_root_dir;
+
+static char input_buffer[INPUT_BUFFER_SIZE];
+static char result_buffer[BUFFER_SIZE];
+static char not_called_message[11] = "not called";
+
+static u8 temporary_buffer[BUFFER_SIZE];
+
+static size_t get_avail_bytes(void) {
+ return BUFFER_SIZE - strlen(result_buffer);
+}
+static char *get_buffer_end(void) {
+ return result_buffer + strlen(result_buffer);
+}
+
+/** Appends the contents of an acpi_object to the result buffer
+@param result An acpi object holding result data
+@returns 0 if the result could fully be saved, a higher value otherwise
+*/
+static int acpi_result_to_string(union acpi_object *result) {
+ if (result->type == ACPI_TYPE_INTEGER) {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "0x%x", (int)result->integer.value);
+ } else if (result->type == ACPI_TYPE_STRING) {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "\"%*s\"", result->string.length, result->string.pointer);
+ } else if (result->type == ACPI_TYPE_BUFFER) {
+ int i;
+ // do not store more than data if it does not fit. The first element is
+ // just 4 chars, but there is also two bytes from the curly brackets
+ int show_values = min((size_t)result->buffer.length, get_avail_bytes() / 6);
+
+ snprintf(get_buffer_end(), get_avail_bytes(), "{");
+ for (i = 0; i < show_values; i++)
+ sprintf(get_buffer_end(),
+ i == 0 ? "0x%02x" : ", 0x%02x", result->buffer.pointer[i]);
+
+ if (result->buffer.length > show_values) {
+ // if data was truncated, show a trailing comma if there is space
+ snprintf(get_buffer_end(), get_avail_bytes(), ",");
+ return 1;
+ } else {
+ // in case show_values == 0, but the buffer is too small to hold
+ // more values (i.e. the buffer cannot have anything more than "{")
+ snprintf(get_buffer_end(), get_avail_bytes(), "}");
+ }
+ } else if (result->type == ACPI_TYPE_PACKAGE) {
+ int i;
+ snprintf(get_buffer_end(), get_avail_bytes(), "[");
+ for (i=0; i<result->package.count; i++) {
+ if (i > 0)
+ snprintf(get_buffer_end(), get_avail_bytes(), ", ");
+
+ // abort if there is no more space available
+ if (!get_avail_bytes() || acpi_result_to_string(&result->package.elements[i]))
+ return 1;
+ }
+ snprintf(get_buffer_end(), get_avail_bytes(), "]");
+ } else {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "Object type 0x%x\n", result->type);
+ }
+
+ // return 0 if there are still bytes available, 1 otherwise
+ return !get_avail_bytes();
+}
+
+/**
+@param method The full name of ACPI method to call
+@param argc The number of parameters
+@param argv A pre-allocated array of arguments of type acpi_object
+*/
+static void do_acpi_call(const char * method, int argc, union acpi_object *argv)
+{
+ acpi_status status;
+ acpi_handle handle;
+ struct acpi_object_list arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Calling %s\n", method);
+#endif
+
+ // get the handle of the method, must be a fully qualified path
+ status = acpi_get_handle(NULL, (acpi_string) method, &handle);
+
+ if (ACPI_FAILURE(status))
+ {
+ snprintf(result_buffer, BUFFER_SIZE, "Error: %s", acpi_format_exception(status));
+ printk(KERN_ERR "acpi_call: Cannot get handle: %s\n", result_buffer);
+ return;
+ }
+
+ // prepare parameters
+ arg.count = argc;
+ arg.pointer = argv;
+
+ // call the method
+ status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
+ if (ACPI_FAILURE(status))
+ {
+ snprintf(result_buffer, BUFFER_SIZE, "Error: %s", acpi_format_exception(status));
+ printk(KERN_ERR "acpi_call: Method call failed: %s\n", result_buffer);
+ return;
+ }
+
+ // reset the result buffer
+ *result_buffer = '\0';
+ acpi_result_to_string(buffer.pointer);
+ kfree(buffer.pointer);
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Call successful: %s\n", result_buffer);
+#endif
+}
+
+/** Decodes 2 hex characters to an u8 int
+*/
+u8 decodeHex(char *hex) {
+ char buf[3] = { hex[0], hex[1], 0};
+ return (u8) simple_strtoul(buf, NULL, 16);
+}
+
+/** Parses method name and arguments
+@param input Input string to be parsed. Modified in the process.
+@param nargs Set to number of arguments parsed (output)
+@param args
+*/
+static char *parse_acpi_args(char *input, int *nargs, union acpi_object **args)
+{
+ char *s = input;
+ int i;
+
+ *nargs = 0;
+ *args = NULL;
+
+ // the method name is separated from the arguments by a space
+ while (*s && *s != ' ')
+ s++;
+ // if no space is found, return 0 arguments
+ if (*s == 0)
+ return input;
+
+ *args = (union acpi_object *) kmalloc(MAX_ACPI_ARGS * sizeof(union acpi_object), GFP_KERNEL);
+ if (!*args) {
+ printk(KERN_ERR "acpi_call: unable to allocate buffer\n");
+ return NULL;
+ }
+
+ while (*s) {
+ if (*s == ' ') {
+ if (*nargs == 0)
+ *s = 0; // change first space to nul
+ ++ *nargs;
+ ++ s;
+ } else {
+ union acpi_object *arg = (*args) + (*nargs - 1);
+ if (*s == '"') {
+ // decode string
+ arg->type = ACPI_TYPE_STRING;
+ arg->string.pointer = ++s;
+ arg->string.length = 0;
+ while (*s && *s++ != '"')
+ arg->string.length ++;
+ // skip the last "
+ if (*s == '"')
+ ++s;
+ } else if (*s == 'b') {
+ // decode buffer - bXXXX
+ char *p = ++s;
+ int len = 0, i;
+ u8 *buf = NULL;
+
+ while (*p && *p!=' ')
+ p++;
+
+ len = p - s;
+ if (len % 2 == 1) {
+ printk(KERN_ERR "acpi_call: buffer arg%d is not multiple of 8 bits\n", *nargs);
+ --*nargs;
+ goto err;
+ }
+ len /= 2;
+
+ buf = (u8*) kmalloc(len, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "acpi_call: unable to allocate buffer\n");
+ --*nargs;
+ goto err;
+ }
+ for (i=0; i<len; i++) {
+ buf[i] = decodeHex(s + i*2);
+ }
+ s = p;
+
+ arg->type = ACPI_TYPE_BUFFER;
+ arg->buffer.pointer = buf;
+ arg->buffer.length = len;
+ } else if (*s == '{') {
+ // decode buffer - { b1, b2 ...}
+ u8 *buf = temporary_buffer;
+ arg->type = ACPI_TYPE_BUFFER;
+ arg->buffer.pointer = buf;
+ arg->buffer.length = 0;
+ while (*s && *s++ != '}') {
+ if (buf >= temporary_buffer + sizeof(temporary_buffer)) {
+ printk(KERN_ERR "acpi_call: buffer arg%d is truncated because the buffer is full\n", *nargs);
+ // clear remaining arguments
+ while (*s && *s != '}')
+ ++s;
+ break;
+ }
+ else if (*s >= '0' && *s <= '9') {
+ // decode integer into buffer
+ arg->buffer.length ++;
+ if (s[0] == '0' && s[1] == 'x')
+ *buf++ = simple_strtol(s+2, 0, 16);
+ else
+ *buf++ = simple_strtol(s, 0, 10);
+ }
+ // skip until space or comma or '}'
+ while (*s && *s != ' ' && *s != ',' && *s != '}')
+ ++s;
+ }
+ // store the result in new allocated buffer
+ buf = (u8*) kmalloc(arg->buffer.length, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "acpi_call: unable to allocate buffer\n");
+ --*nargs;
+ goto err;
+ }
+ memcpy(buf, temporary_buffer, arg->buffer.length);
+ arg->buffer.pointer = buf;
+ } else {
+ // decode integer, N or 0xN
+ arg->type = ACPI_TYPE_INTEGER;
+ if (s[0] == '0' && s[1] == 'x') {
+ arg->integer.value = simple_strtol(s+2, 0, 16);
+ } else {
+ arg->integer.value = simple_strtol(s, 0, 10);
+ }
+ while (*s && *s != ' ') {
+ ++s;
+ }
+ }
+ }
+ }
+
+ return input;
+
+err:
+ for (i=0; i<*nargs; i++)
+ if ((*args)[i].type == ACPI_TYPE_BUFFER && (*args)[i].buffer.pointer)
+ kfree((*args)[i].buffer.pointer);
+ kfree(*args);
+ return NULL;
+}
+
+/** procfs write callback. Called when writing into /proc/acpi/call.
+*/
+#ifdef HAVE_PROC_CREATE
+static ssize_t acpi_proc_write( struct file *filp, const char __user *buff,
+ size_t len, loff_t *data )
+#else
+static int acpi_proc_write( struct file *filp, const char __user *buff,
+ unsigned long len, void *data )
+#endif
+{
+ union acpi_object *args;
+ int nargs, i;
+ char *method;
+
+ memset(input_buffer, 0, INPUT_BUFFER_SIZE);
+ if (len > sizeof(input_buffer) - 1) {
+#ifdef HAVE_PROC_CREATE
+ printk(KERN_ERR "acpi_call: Input too long! (%zu)\n", len);
+#else
+ printk(KERN_ERR "acpi_call: Input too long! (%lu)\n", len);
+#endif
+ return -ENOSPC;
+ }
+
+ if (copy_from_user( input_buffer, buff, len )) {
+ return -EFAULT;
+ }
+ input_buffer[len] = '\0';
+ if (input_buffer[len-1] == '\n')
+ input_buffer[len-1] = '\0';
+
+ method = parse_acpi_args(input_buffer, &nargs, &args);
+ if (method) {
+ do_acpi_call(method, nargs, args);
+ if (args) {
+ for (i=0; i<nargs; i++)
+ if (args[i].type == ACPI_TYPE_BUFFER)
+ kfree(args[i].buffer.pointer);
+ }
+ }
+ if (args)
+ kfree(args);
+
+ return len;
+}
+
+/** procfs 'call' read callback. Called when reading the content of /proc/acpi/call.
+Returns the last call status:
+- "not called" when no call was previously issued
+- "failed" if the call failed
+- "ok" if the call succeeded
+*/
+#ifdef HAVE_PROC_CREATE
+static ssize_t acpi_proc_read( struct file *filp, char __user *buff,
+ size_t count, loff_t *off )
+{
+ ssize_t ret;
+ int len = strlen(result_buffer);
+
+ if(len == 0) {
+ ret = simple_read_from_buffer(buff, count, off, not_called_message, strlen(not_called_message) + 1);
+ } else if(len + 1 > count) {
+ // user buffer is too small
+ ret = 0;
+ } else if(*off == len + 1) {
+ // we're done
+ ret = 0;
+ result_buffer[0] = '\0';
+ } else {
+ // output the current result buffer
+ ret = simple_read_from_buffer(buff, count, off, result_buffer, len + 1);
+ *off = ret;
+ }
+
+ return ret;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
+static struct proc_ops proc_acpi_operations = {
+ .proc_read = acpi_proc_read,
+ .proc_write = acpi_proc_write,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
+ .proc_lseek = default_llseek,
+#endif
+};
+#else
+static struct file_operations proc_acpi_operations = {
+ .owner = THIS_MODULE,
+ .read = acpi_proc_read,
+ .write = acpi_proc_write,
+};
+#endif
+
+#else
+static int acpi_proc_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ if (off > 0) {
+ *eof = 1;
+ return 0;
+ }
+
+ // output the current result buffer
+ len = strlen(result_buffer);
+ memcpy(page, result_buffer, len + 1);
+
+ // initialize the result buffer for later
+ strcpy(result_buffer, "not called");
+
+ return len;
+}
+#endif
+
+/** module initialization function */
+static int __init init_acpi_call(void)
+{
+#ifdef HAVE_PROC_CREATE
+ struct proc_dir_entry *acpi_entry = proc_create("call",
+ 0660,
+ acpi_root_dir,
+ &proc_acpi_operations);
+#else
+ struct proc_dir_entry *acpi_entry = create_proc_entry("call", 0660, acpi_root_dir);
+#endif
+
+ strcpy(result_buffer, "not called");
+
+ if (acpi_entry == NULL) {
+ printk(KERN_ERR "acpi_call: Couldn't create proc entry\n");
+ return -ENOMEM;
+ }
+
+#ifndef HAVE_PROC_CREATE
+ acpi_entry->write_proc = acpi_proc_write;
+ acpi_entry->read_proc = acpi_proc_read;
+#endif
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Module loaded successfully\n");
+#endif
+
+ return 0;
+}
+
+static void __exit unload_acpi_call(void)
+{
+ remove_proc_entry("call", acpi_root_dir);
+
+#ifdef DEBUG
+ printk(KERN_INFO "acpi_call: Module unloaded successfully\n");
+#endif
+}
+
+module_init(init_acpi_call);
+module_exit(unload_acpi_call);
\ No newline at end of file
--
2.42.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,972 @@
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index fd61dba88..3220d96fc 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -26,7 +26,9 @@
#include <linux/dmi.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/sysfs.h>
#include <linux/platform_data/x86/asus-wmi.h>
+#include <linux/platform_device.h>
#include <linux/input/mt.h>
#include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
#include <linux/power_supply.h>
@@ -94,6 +96,435 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
+/*
+ * USB buffers to be used in a control transfer to make the joystick change buttons mode and scancodes
+ * 0 is default (game_mode with back buttons sending F17 and F18 instead of F15 for both as when unconfigured)
+ * 1 is mouse mode: back buttons still are F17 and F18
+ * 2 is macro mode
+ */
+static const u8 rc71l_mode_switch_commands[][23][64] = {
+ {
+ {
+ 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ {
+ 0x5A, 0xD1, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x02, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x99, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x02, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x9B, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x02, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x02, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x96, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x0D, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ {
+ 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ {
+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ }
+};
+
struct asus_kbd_leds {
struct led_classdev cdev;
struct hid_device *hdev;
@@ -103,6 +534,25 @@ struct asus_kbd_leds {
bool removed;
};
+enum rc71l_controller_mode {
+ rc71l_gamepad_mode,
+ rc71l_mouse_mode,
+ rc71l_macro_mode,
+};
+
+struct asus_rc71l {
+ unsigned int usb_pipe;
+
+ struct platform_device *mcu_dev;
+
+ struct mutex mutex; /* Mutex that protects everything below it */
+
+ enum rc71l_controller_mode mode;
+
+ u8 usb_in_buf[32];
+ u8 usb_out_buf[64]; /* A temporary buffer to hold data that gets sent over USB (must be accessed upon locking the appropriate mutex) */
+};
+
struct asus_touchpad_info {
int max_x;
int max_y;
@@ -127,6 +577,7 @@ struct asus_drvdata {
int battery_stat;
bool battery_in_query;
unsigned long battery_next_query;
+ struct asus_rc71l *rc71l_data;
};
static int asus_report_battery(struct asus_drvdata *, u8 *, int);
@@ -189,6 +640,245 @@ static const struct asus_touchpad_info medion_e1239t_tp = {
.report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */,
};
+/**
+ * This function reads data over the USB device on the ROG Ally.
+ * Unlike outgoing traffic the inbound always performs 32-bytes transfers.
+ *
+ * PRE:
+ * - rc71l internal mutex MUST be locked
+ */
+static int rc71l_usb_read(struct hid_device * hdev) {
+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ const int retval = usb_control_msg_recv(dev, 0x80, 0x01, 0xa1, 0x035A, 0x0002, (void*)&rc71l_drvdata->usb_in_buf[0], 32, 250, GFP_KERNEL);
+
+ if (retval < 0) {
+ hid_err(hdev, "Ally read failed performing control read, error %d\n", retval);
+ goto rc71l_usb_read_err;
+ }
+
+ const char* b = (const u8*)&rc71l_drvdata->usb_in_buf[0];
+ hid_info(hdev, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9],
+ b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19],
+ b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29],
+ b[30], b[31]
+ );
+
+rc71l_usb_read_err:
+ return retval;
+}
+
+/**
+ * This function writes a command over the USB device on the ROG Ally.
+ * The ROG Ally accepts 64-bytes long messages as commands: as such at most 64-bytes will be sent
+ * and unused bytes will be zeroed out.
+ *
+ * PRE:
+ * - rc71l internal mutex MUST be locked
+ */
+static int rc71l_usb_write(struct hid_device * hdev, const void* buf, size_t buf_sz) {
+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ if (buf_sz > 64) {
+ hid_err(hdev, "Bug in the kernel: cannot write more than 64-bytes\n");
+
+ return -EINVAL;
+ }
+
+ // make sure bytes in excess will be zeroes and copy the user-provided buffer
+ memset((void*)&rc71l_drvdata->usb_out_buf[0], 0, 64);
+ memcpy((void*)&rc71l_drvdata->usb_out_buf[0], buf, buf_sz);
+
+ /* send the data out the bulk port */
+ const int retval = usb_control_msg(dev, rc71l_drvdata->usb_pipe, 0x09, 0x21, 0x035A, 0x0002, (void*)&rc71l_drvdata->usb_out_buf[0], 64, 250);
+ if (retval < 0) {
+ hid_err(hdev,
+ "Failed submitting control write error %d\n", retval);
+
+ goto rc71l_usb_write_err;
+ }
+
+rc71l_usb_write_err:
+ return retval < 0 ? retval : 0;
+}
+
+static int rc71l_mode_change(struct hid_device * hdev, enum rc71l_controller_mode new_mode) {
+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ int ret = 0;
+
+ size_t packets_group = 0;
+ switch (new_mode) {
+ case rc71l_gamepad_mode:
+ packets_group = 0;
+ break;
+
+ case rc71l_mouse_mode:
+ packets_group = 1;
+ break;
+
+ case rc71l_macro_mode:
+ packets_group = 2;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ for (int i = 0; (i < 23) && (ret == 0); ++i) {
+ ret = rc71l_usb_write(hdev, (const void*)&rc71l_mode_switch_commands[packets_group][i][0], 64);
+ if (ret > 0) {
+ hid_err(hdev, "Ally controller mode switch %d/23 error %d\n", i, ret);
+ goto rc71l_mode_change_err;
+ }
+ }
+
+ // controller mode has been switched successfully: change that in driver data
+ if (ret == 0) {
+ hid_info(hdev, "ROG Ally [RC71L] controller mode switch succeeded\n");
+ rc71l_drvdata->mode = new_mode;
+ }
+
+rc71l_mode_change_err:
+ return ret;
+}
+
+static ssize_t __maybe_unused mode_show(struct device *raw_dev, struct device_attribute *attr, char *buf) {
+ struct platform_device *const pdev = to_platform_device(raw_dev);
+ struct hid_device *const hdev = platform_get_drvdata(pdev);
+ if (hdev == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_drvdata *const drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *const rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&rc71l_drvdata->mutex);
+ int current_mode = 0;
+ switch (rc71l_drvdata->mode) {
+ case rc71l_gamepad_mode:
+ current_mode = 0;
+ break;
+
+ case rc71l_mouse_mode:
+ current_mode = 1;
+ break;
+
+ case rc71l_macro_mode:
+ current_mode = 2;
+ break;
+
+ default:
+ mutex_unlock(&rc71l_drvdata->mutex);
+ return -EINVAL;
+ }
+ mutex_unlock(&rc71l_drvdata->mutex);
+
+ return sysfs_emit(buf, "%d\n", (int)current_mode);
+}
+
+static ssize_t __maybe_unused mode_store(struct device *raw_dev, struct device_attribute *attr, const char *buf, size_t count) {
+ struct platform_device *const pdev = to_platform_device(raw_dev);
+ struct hid_device *const hdev = platform_get_drvdata(pdev);
+ if (hdev == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_drvdata *const drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev);
+ if (drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ struct asus_rc71l *const rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata == NULL) {
+ return -EINVAL;
+ }
+
+ int res = -EINVAL;
+ int val = -EINVAL;
+ res = kstrtoint(buf, 0, &val);
+ if (res)
+ return res;
+
+ switch (val) {
+ case 0:
+ mutex_lock(&rc71l_drvdata->mutex);
+ res = rc71l_mode_change(hdev, rc71l_gamepad_mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+ break;
+
+ case 1:
+ mutex_lock(&rc71l_drvdata->mutex);
+ res = rc71l_mode_change(hdev, rc71l_mouse_mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+ break;
+
+ case 2:
+ mutex_lock(&rc71l_drvdata->mutex);
+ res = rc71l_mode_change(hdev, rc71l_macro_mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ hid_err(hdev, "Ally controller mode switch to %d mode op result: %d\n", val, res);
+
+ return count;
+}
+
+DEVICE_ATTR_RW(mode);
+
+static struct attribute *rc71l_input_attrs[] = {
+ &dev_attr_mode.attr,
+ NULL
+};
+
+static const struct attribute_group mcu_attr_group = {
+ .name = "input",
+ .attrs = rc71l_input_attrs,
+};
+
static void asus_report_contact_down(struct asus_drvdata *drvdat,
int toolType, u8 *data)
{
@@ -386,7 +1076,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size
unsigned char *dmabuf;
int ret;
- dmabuf = kmemdup(buf, buf_size, GFP_KERNEL);
+ dmabuf = kmemdup((const void*)buf, buf_size, GFP_KERNEL);
if (!dmabuf)
return -ENOMEM;
@@ -897,6 +1587,10 @@ static int asus_input_mapping(struct hid_device *hdev,
case 0xb3: asus_map_key_clear(KEY_PROG3); break; /* Fn+Left next aura */
case 0x6a: asus_map_key_clear(KEY_F13); break; /* Screenpad toggle */
case 0x4b: asus_map_key_clear(KEY_F14); break; /* Arrows/Pg-Up/Dn toggle */
+ case 0xa5: asus_map_key_clear(KEY_F15); break; /* ROG Ally left back */
+ case 0xa6: asus_map_key_clear(KEY_F16); break; /* ROG Ally QAM button */
+ case 0xa7: asus_map_key_clear(KEY_F17); break; /* ROG Ally ROG long-press */
+ case 0xa8: asus_map_key_clear(KEY_F18); break; /* ROG Ally ROG long-press-release */
default:
@@ -1000,16 +1694,108 @@ static int asus_start_multitouch(struct hid_device *hdev)
return 0;
}
+#ifdef CONFIG_PM
static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
{
+ int ret = 0;
+
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+ if (drvdata != NULL) {
+ return -EINVAL;
+ }
if (drvdata->tp)
return asus_start_multitouch(hdev);
- return 0;
+ return ret;
}
+static int __maybe_unused asus_resume(struct hid_device *hdev)
+{
+ int ret = 0;
+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+/*
+ // Controller mode is kept on device sleep
+ if (dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L"))
+ {
+ // Apply the joystick mode switch
+ ret = rog_ally_controller_mode_change(hdev, game_mode);
+
+ hid_err(hdev, "Asus wake, restore controller %d\n", ret);
+ }
+*/
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata != NULL) {
+ mutex_lock(&rc71l_drvdata->mutex);
+ ret = rc71l_mode_change(hdev, rc71l_drvdata->mode);
+ mutex_unlock(&rc71l_drvdata->mutex);
+
+ if (ret < 0) {
+ hid_err(hdev, "ROG Ally [RC71L] failed to reset controller mode: %d\n", ret);
+ goto asus_resume_err;
+ }
+ }
+
+
+ /*
+ * On some devices such as the Asus RC71L leds are reset to default after sleep and sysfs attribute will report
+ * something that won't be true: resetting the user-provided value is necessary to maintain coherency and avoid
+ * flashing full brightness leds in face of the user.
+ */
+ if (drvdata->kbd_backlight) {
+ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, drvdata->kbd_backlight->cdev.brightness };
+ ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
+ if (ret < 0) {
+ hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret);
+ goto asus_resume_err;
+ }
+
+ hid_err(hdev, "Asus ROG Ally asus_reset_resume, leds reset: %d at brightness %d\n", ret, (int)drvdata->kbd_backlight->cdev.brightness);
+ }
+
+ asus_resume_err:
+ return ret;
+}
+
+static int __maybe_unused asus_suspend(struct hid_device *hdev, struct pm_message)
+ {
+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+
+ if (drvdata == NULL) {
+ return 0;
+ }
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ int ret = 0;
+
+ if (dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L")) {
+ // Send the USB ABORT_PIPE command
+ int result = usb_control_msg(
+ dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE,
+ USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT,
+ USB_ENDPOINT_HALT, 0x02, NULL, 0, 1000);
+
+ if (result < 0) {
+ printk("USB ABORT_PIPE failed: %d\n", result);
+ } else {
+ printk("USB ABORT_PIPE succeeded\n");
+ }
+ }
+
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata != NULL) {
+ mutex_lock(&rc71l_drvdata->mutex);
+ // TODO: send ABORT_PIPE here
+ mutex_unlock(&rc71l_drvdata->mutex);
+ }
+
+ return ret;
+}
+#endif
+
static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret;
@@ -1021,6 +1807,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
return -ENOMEM;
}
+ drvdata->rc71l_data = NULL;
+
hid_set_drvdata(hdev, drvdata);
drvdata->quirks = id->driver_data;
@@ -1109,6 +1897,51 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_stop_hw;
}
+ if ((dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L")) && (hdev->rsize > 9) && (hdev->rdesc[7] == 0x85) && (hdev->rdesc[8] == 0x5a))
+ {
+ drvdata->rc71l_data = devm_kzalloc(&hdev->dev, sizeof(*drvdata->rc71l_data), GFP_KERNEL);
+ if (drvdata->rc71l_data == NULL) {
+ hid_err(hdev, "Can't alloc Asus ROG Ally [RC71L] descriptor\n");
+ ret = -ENOMEM;
+ goto err_stop_hw;
+ }
+
+ mutex_init(&drvdata->rc71l_data->mutex);
+
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ // default controller mode
+ drvdata->rc71l_data->mode = rc71l_gamepad_mode;
+
+ // usb_device and endpoint
+ drvdata->rc71l_data->usb_pipe = usb_sndctrlpipe(dev, 0);
+
+ // apply the default controller mode
+ mutex_lock(&drvdata->rc71l_data->mutex);
+ ret = rc71l_mode_change(hdev, drvdata->rc71l_data->mode);
+ mutex_unlock(&drvdata->rc71l_data->mutex);
+
+ if (ret < 0) {
+ hid_err(hdev, "Asus ROG Ally [RC71L] error setting the default controller mode: %d\n", ret);
+ goto err_stop_hw;
+ }
+
+ drvdata->rc71l_data->mcu_dev = platform_device_register_simple("asus-mcu", 0, NULL, 0);
+ if (IS_ERR(drvdata->rc71l_data->mcu_dev)) {
+ hid_err(hdev, "Error registering MCU platform device: %ld\n", PTR_ERR(drvdata->rc71l_data->mcu_dev));
+ goto err_stop_hw;
+ }
+
+ platform_set_drvdata(drvdata->rc71l_data->mcu_dev, hdev);
+
+ ret = devm_device_add_group(&drvdata->rc71l_data->mcu_dev->dev, &mcu_attr_group);
+ if (ret != 0) {
+ platform_device_unregister(drvdata->rc71l_data->mcu_dev);
+ goto err_stop_hw;
+ }
+ }
+
if (drvdata->tp) {
drvdata->input->name = "Asus TouchPad";
} else {
@@ -1140,6 +1973,16 @@ static void asus_remove(struct hid_device *hdev)
cancel_work_sync(&drvdata->kbd_backlight->work);
}
+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data;
+ if (rc71l_drvdata != NULL) {
+ platform_device_unregister(rc71l_drvdata->mcu_dev);
+
+ mutex_lock(&rc71l_drvdata->mutex);
+ platform_device_unregister(rc71l_drvdata->mcu_dev);
+ // TODO: perform cleanup operations
+ mutex_unlock(&rc71l_drvdata->mutex);
+ }
+
hid_hw_stop(hdev);
}
@@ -1258,6 +2101,9 @@ static const struct hid_device_id asus_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3),
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+ USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY),
+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
QUIRK_ROG_CLAYMORE_II_KEYBOARD },
@@ -1294,6 +2140,8 @@ static struct hid_driver asus_driver = {
.input_configured = asus_input_configured,
#ifdef CONFIG_PM
.reset_resume = asus_reset_resume,
+ .resume = asus_resume,
+ .suspend = asus_suspend,
#endif
.event = asus_event,
.raw_event = asus_raw_event
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index d10ccfa17..213492ee8 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -208,6 +208,7 @@
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe
#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
--
2.43.0

View File

@ -0,0 +1,719 @@
From 309712fae7491a876359ddda6e4cf8944f454731 Mon Sep 17 00:00:00 2001
From: GloriousEggroll <gloriouseggroll@gmail.com>
Date: Wed, 13 Sep 2023 17:59:59 -0600
Subject: [PATCH] OpenRGB
---
drivers/i2c/busses/Kconfig | 9 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-nct6775.c | 647 +++++++++++++++++++++++++++++++
drivers/i2c/busses/i2c-piix4.c | 4 +-
4 files changed, 659 insertions(+), 2 deletions(-)
create mode 100644 drivers/i2c/busses/i2c-nct6775.c
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 9cfe8fc50..efc3b0c0b 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -229,6 +229,15 @@ config I2C_CHT_WC
combined with a FUSB302 Type-C port-controller as such it is advised
to also select CONFIG_TYPEC_FUSB302=m.
+config I2C_NCT6775
+ tristate "Nuvoton NCT6775 and compatible SMBus controller"
+ help
+ If you say yes to this option, support will be included for the
+ Nuvoton NCT6775 and compatible SMBus controllers.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-nct6775.
+
config I2C_NFORCE2
tristate "Nvidia nForce2, nForce3 and nForce4"
depends on PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index af56fe2c7..76be74584 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_CHT_WC) += i2c-cht-wc.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_ISCH) += i2c-isch.o
obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o
+obj-$(CONFIG_I2C_NCT6775) += i2c-nct6775.o
obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o
obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o
obj-$(CONFIG_I2C_NVIDIA_GPU) += i2c-nvidia-gpu.o
diff --git a/drivers/i2c/busses/i2c-nct6775.c b/drivers/i2c/busses/i2c-nct6775.c
new file mode 100644
index 000000000..0462f0952
--- /dev/null
+++ b/drivers/i2c/busses/i2c-nct6775.c
@@ -0,0 +1,647 @@
+/*
+ * i2c-nct6775 - Driver for the SMBus master functionality of
+ * Nuvoton NCT677x Super-I/O chips
+ *
+ * Copyright (C) 2019 Adam Honse <calcprogrammer1@gmail.com>
+ *
+ * Derived from nct6775 hwmon driver
+ * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/dmi.h>
+#include <linux/io.h>
+#include <linux/nospec.h>
+
+#define DRVNAME "i2c-nct6775"
+
+/* Nuvoton SMBus address offsets */
+#define SMBHSTDAT (0 + nuvoton_nct6793d_smba)
+#define SMBBLKSZ (1 + nuvoton_nct6793d_smba)
+#define SMBHSTCMD (2 + nuvoton_nct6793d_smba)
+#define SMBHSTIDX (3 + nuvoton_nct6793d_smba) //Index field is the Command field on other controllers
+#define SMBHSTCTL (4 + nuvoton_nct6793d_smba)
+#define SMBHSTADD (5 + nuvoton_nct6793d_smba)
+#define SMBHSTERR (9 + nuvoton_nct6793d_smba)
+#define SMBHSTSTS (0xE + nuvoton_nct6793d_smba)
+
+/* Command register */
+#define NCT6793D_READ_BYTE 0
+#define NCT6793D_READ_WORD 1
+#define NCT6793D_READ_BLOCK 2
+#define NCT6793D_BLOCK_WRITE_READ_PROC_CALL 3
+#define NCT6793D_PROC_CALL 4
+#define NCT6793D_WRITE_BYTE 8
+#define NCT6793D_WRITE_WORD 9
+#define NCT6793D_WRITE_BLOCK 10
+
+/* Control register */
+#define NCT6793D_MANUAL_START 128
+#define NCT6793D_SOFT_RESET 64
+
+/* Error register */
+#define NCT6793D_NO_ACK 32
+
+/* Status register */
+#define NCT6793D_FIFO_EMPTY 1
+#define NCT6793D_FIFO_FULL 2
+#define NCT6793D_MANUAL_ACTIVE 4
+
+#define NCT6775_LD_SMBUS 0x0B
+
+/* Other settings */
+#define MAX_RETRIES 400
+
+enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793,
+ nct6795, nct6796, nct6798 };
+
+struct nct6775_sio_data {
+ int sioreg;
+ enum kinds kind;
+};
+
+/* used to set data->name = nct6775_device_names[data->sio_kind] */
+static const char * const nct6775_device_names[] = {
+ "nct6106",
+ "nct6775",
+ "nct6776",
+ "nct6779",
+ "nct6791",
+ "nct6792",
+ "nct6793",
+ "nct6795",
+ "nct6796",
+ "nct6798",
+};
+
+static const char * const nct6775_sio_names[] __initconst = {
+ "NCT6106D",
+ "NCT6775F",
+ "NCT6776D/F",
+ "NCT6779D",
+ "NCT6791D",
+ "NCT6792D",
+ "NCT6793D",
+ "NCT6795D",
+ "NCT6796D",
+ "NCT6798D",
+};
+
+#define SIO_REG_LDSEL 0x07 /* Logical device select */
+#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
+#define SIO_REG_SMBA 0x62 /* SMBus base address register */
+
+#define SIO_NCT6106_ID 0xc450
+#define SIO_NCT6775_ID 0xb470
+#define SIO_NCT6776_ID 0xc330
+#define SIO_NCT6779_ID 0xc560
+#define SIO_NCT6791_ID 0xc800
+#define SIO_NCT6792_ID 0xc910
+#define SIO_NCT6793_ID 0xd120
+#define SIO_NCT6795_ID 0xd350
+#define SIO_NCT6796_ID 0xd420
+#define SIO_NCT6798_ID 0xd428
+#define SIO_ID_MASK 0xFFF0
+
+static inline void
+superio_outb(int ioreg, int reg, int val)
+{
+ outb(reg, ioreg);
+ outb(val, ioreg + 1);
+}
+
+static inline int
+superio_inb(int ioreg, int reg)
+{
+ outb(reg, ioreg);
+ return inb(ioreg + 1);
+}
+
+static inline void
+superio_select(int ioreg, int ld)
+{
+ outb(SIO_REG_LDSEL, ioreg);
+ outb(ld, ioreg + 1);
+}
+
+static inline int
+superio_enter(int ioreg)
+{
+ /*
+ * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
+ */
+ if (!request_muxed_region(ioreg, 2, DRVNAME))
+ return -EBUSY;
+
+ outb(0x87, ioreg);
+ outb(0x87, ioreg);
+
+ return 0;
+}
+
+static inline void
+superio_exit(int ioreg)
+{
+ outb(0xaa, ioreg);
+ outb(0x02, ioreg);
+ outb(0x02, ioreg + 1);
+ release_region(ioreg, 2);
+}
+
+/*
+ * ISA constants
+ */
+
+#define IOREGION_ALIGNMENT (~7)
+#define IOREGION_LENGTH 2
+#define ADDR_REG_OFFSET 0
+#define DATA_REG_OFFSET 1
+
+#define NCT6775_REG_BANK 0x4E
+#define NCT6775_REG_CONFIG 0x40
+
+static struct i2c_adapter *nct6775_adapter;
+
+struct i2c_nct6775_adapdata {
+ unsigned short smba;
+};
+
+/* Return negative errno on error. */
+static s32 nct6775_access(struct i2c_adapter * adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data * data)
+{
+ struct i2c_nct6775_adapdata *adapdata = i2c_get_adapdata(adap);
+ unsigned short nuvoton_nct6793d_smba = adapdata->smba;
+ int i, len, cnt;
+ union i2c_smbus_data tmp_data;
+ int timeout = 0;
+
+ tmp_data.word = 0;
+ cnt = 0;
+ len = 0;
+
+ outb_p(NCT6793D_SOFT_RESET, SMBHSTCTL);
+
+ switch (size) {
+ case I2C_SMBUS_QUICK:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ tmp_data.byte = data->byte;
+ case I2C_SMBUS_BYTE:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ outb_p(command, SMBHSTIDX);
+ if (read_write == I2C_SMBUS_WRITE) {
+ outb_p(tmp_data.byte, SMBHSTDAT);
+ outb_p(NCT6793D_WRITE_BYTE, SMBHSTCMD);
+ }
+ else {
+ outb_p(NCT6793D_READ_BYTE, SMBHSTCMD);
+ }
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ outb_p(command, SMBHSTIDX);
+ if (read_write == I2C_SMBUS_WRITE) {
+ outb_p(data->word & 0xff, SMBHSTDAT);
+ outb_p((data->word & 0xff00) >> 8, SMBHSTDAT);
+ outb_p(NCT6793D_WRITE_WORD, SMBHSTCMD);
+ }
+ else {
+ outb_p(NCT6793D_READ_WORD, SMBHSTCMD);
+ }
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+ outb_p((addr << 1) | read_write,
+ SMBHSTADD);
+ outb_p(command, SMBHSTIDX);
+ if (read_write == I2C_SMBUS_WRITE) {
+ len = data->block[0];
+ if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+ return -EINVAL;
+ outb_p(len, SMBBLKSZ);
+
+ cnt = 1;
+ if (len >= 4) {
+ for (i = cnt; i <= 4; i++) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len -= 4;
+ cnt += 4;
+ }
+ else {
+ for (i = cnt; i <= len; i++ ) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len = 0;
+ }
+
+ outb_p(NCT6793D_WRITE_BLOCK, SMBHSTCMD);
+ }
+ else {
+ return -ENOTSUPP;
+ }
+ break;
+ default:
+ dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+ return -EOPNOTSUPP;
+ }
+
+ outb_p(NCT6793D_MANUAL_START, SMBHSTCTL);
+
+ while ((size == I2C_SMBUS_BLOCK_DATA) && (len > 0)) {
+ if (read_write == I2C_SMBUS_WRITE) {
+ timeout = 0;
+ while ((inb_p(SMBHSTSTS) & NCT6793D_FIFO_EMPTY) == 0)
+ {
+ if(timeout > MAX_RETRIES)
+ {
+ return -ETIMEDOUT;
+ }
+ usleep_range(250, 500);
+ timeout++;
+ }
+
+ //Load more bytes into FIFO
+ if (len >= 4) {
+ for (i = cnt; i <= (cnt + 4); i++) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len -= 4;
+ cnt += 4;
+ }
+ else {
+ for (i = cnt; i <= (cnt + len); i++) {
+ outb_p(data->block[i], SMBHSTDAT);
+ }
+
+ len = 0;
+ }
+ }
+ else {
+ return -ENOTSUPP;
+ }
+
+ }
+
+ //wait for manual mode to complete
+ timeout = 0;
+ while ((inb_p(SMBHSTSTS) & NCT6793D_MANUAL_ACTIVE) != 0)
+ {
+ if(timeout > MAX_RETRIES)
+ {
+ return -ETIMEDOUT;
+ }
+ usleep_range(250, 500);
+ timeout++;
+ }
+
+ if ((inb_p(SMBHSTERR) & NCT6793D_NO_ACK) != 0) {
+ return -ENXIO;
+ }
+ else if ((read_write == I2C_SMBUS_WRITE) || (size == I2C_SMBUS_QUICK)) {
+ return 0;
+ }
+
+ switch (size) {
+ case I2C_SMBUS_QUICK:
+ case I2C_SMBUS_BYTE_DATA:
+ data->byte = inb_p(SMBHSTDAT);
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ data->word = inb_p(SMBHSTDAT) + (inb_p(SMBHSTDAT) << 8);
+ break;
+ }
+ return 0;
+}
+
+static u32 nct6775_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static const struct i2c_algorithm smbus_algorithm = {
+ .smbus_xfer = nct6775_access,
+ .functionality = nct6775_func,
+};
+
+static int nct6775_add_adapter(unsigned short smba, const char *name, struct i2c_adapter **padap)
+{
+ struct i2c_adapter *adap;
+ struct i2c_nct6775_adapdata *adapdata;
+ int retval;
+
+ adap = kzalloc(sizeof(*adap), GFP_KERNEL);
+ if (adap == NULL) {
+ return -ENOMEM;
+ }
+
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adap->algo = &smbus_algorithm;
+
+ adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL);
+ if (adapdata == NULL) {
+ kfree(adap);
+ return -ENOMEM;
+ }
+
+ adapdata->smba = smba;
+
+ snprintf(adap->name, sizeof(adap->name),
+ "SMBus NCT67xx adapter%s at %04x", name, smba);
+
+ i2c_set_adapdata(adap, adapdata);
+
+ retval = i2c_add_adapter(adap);
+ if (retval) {
+ kfree(adapdata);
+ kfree(adap);
+ return retval;
+ }
+
+ *padap = adap;
+ return 0;
+}
+
+static void nct6775_remove_adapter(struct i2c_adapter *adap)
+{
+ struct i2c_nct6775_adapdata *adapdata = i2c_get_adapdata(adap);
+
+ if (adapdata->smba) {
+ i2c_del_adapter(adap);
+ kfree(adapdata);
+ kfree(adap);
+ }
+}
+
+//static SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
+
+/*
+ * when Super-I/O functions move to a separate file, the Super-I/O
+ * bus will manage the lifetime of the device and this module will only keep
+ * track of the nct6775 driver. But since we use platform_device_alloc(), we
+ * must keep track of the device
+ */
+static struct platform_device *pdev[2];
+
+static int nct6775_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
+ DRVNAME))
+ return -EBUSY;
+
+ switch (sio_data->kind) {
+ case nct6791:
+ case nct6792:
+ case nct6793:
+ case nct6795:
+ case nct6796:
+ case nct6798:
+ nct6775_add_adapter(res->start, "", &nct6775_adapter);
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ return 0;
+}
+/*
+static void nct6791_enable_io_mapping(int sioaddr)
+{
+ int val;
+
+ val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
+ if (val & 0x10) {
+ pr_info("Enabling hardware monitor logical device mappings.\n");
+ superio_outb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
+ val & ~0x10);
+ }
+}*/
+
+static struct platform_driver i2c_nct6775_driver = {
+ .driver = {
+ .name = DRVNAME,
+// .pm = &nct6775_dev_pm_ops,
+ },
+ .probe = nct6775_probe,
+};
+
+static void __exit i2c_nct6775_exit(void)
+{
+ int i;
+
+ if(nct6775_adapter)
+ nct6775_remove_adapter(nct6775_adapter);
+
+ for (i = 0; i < ARRAY_SIZE(pdev); i++) {
+ if (pdev[i])
+ platform_device_unregister(pdev[i]);
+ }
+ platform_driver_unregister(&i2c_nct6775_driver);
+}
+
+/* nct6775_find() looks for a '627 in the Super-I/O config space */
+static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
+{
+ u16 val;
+ int err;
+ int addr;
+
+ err = superio_enter(sioaddr);
+ if (err)
+ return err;
+
+ val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
+ superio_inb(sioaddr, SIO_REG_DEVID + 1);
+
+ switch (val & SIO_ID_MASK) {
+ case SIO_NCT6106_ID:
+ sio_data->kind = nct6106;
+ break;
+ case SIO_NCT6775_ID:
+ sio_data->kind = nct6775;
+ break;
+ case SIO_NCT6776_ID:
+ sio_data->kind = nct6776;
+ break;
+ case SIO_NCT6779_ID:
+ sio_data->kind = nct6779;
+ break;
+ case SIO_NCT6791_ID:
+ sio_data->kind = nct6791;
+ break;
+ case SIO_NCT6792_ID:
+ sio_data->kind = nct6792;
+ break;
+ case SIO_NCT6793_ID:
+ sio_data->kind = nct6793;
+ break;
+ case SIO_NCT6795_ID:
+ sio_data->kind = nct6795;
+ break;
+ case SIO_NCT6796_ID:
+ sio_data->kind = nct6796;
+ break;
+ case SIO_NCT6798_ID:
+ sio_data->kind = nct6798;
+ break;
+ default:
+ if (val != 0xffff)
+ pr_debug("unsupported chip ID: 0x%04x\n", val);
+ superio_exit(sioaddr);
+ return -ENODEV;
+ }
+
+ /* We have a known chip, find the SMBus I/O address */
+ superio_select(sioaddr, NCT6775_LD_SMBUS);
+ val = (superio_inb(sioaddr, SIO_REG_SMBA) << 8)
+ | superio_inb(sioaddr, SIO_REG_SMBA + 1);
+ addr = val & IOREGION_ALIGNMENT;
+ if (addr == 0) {
+ pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
+ superio_exit(sioaddr);
+ return -ENODEV;
+ }
+
+ //if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
+ // sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
+ // sio_data->kind == nct6796)
+ // nct6791_enable_io_mapping(sioaddr);
+
+ superio_exit(sioaddr);
+ pr_info("Found %s or compatible chip at %#x:%#x\n",
+ nct6775_sio_names[sio_data->kind], sioaddr, addr);
+ sio_data->sioreg = sioaddr;
+
+ return addr;
+}
+
+static int __init i2c_nct6775_init(void)
+{
+ int i, err;
+ bool found = false;
+ int address;
+ struct resource res;
+ struct nct6775_sio_data sio_data;
+ int sioaddr[2] = { 0x2e, 0x4e };
+
+ err = platform_driver_register(&i2c_nct6775_driver);
+ if (err)
+ return err;
+
+ /*
+ * initialize sio_data->kind and sio_data->sioreg.
+ *
+ * when Super-I/O functions move to a separate file, the Super-I/O
+ * driver will probe 0x2e and 0x4e and auto-detect the presence of a
+ * nct6775 hardware monitor, and call probe()
+ */
+ for (i = 0; i < ARRAY_SIZE(pdev); i++) {
+ address = nct6775_find(sioaddr[i], &sio_data);
+ if (address <= 0)
+ continue;
+
+ found = true;
+
+ pdev[i] = platform_device_alloc(DRVNAME, address);
+ if (!pdev[i]) {
+ err = -ENOMEM;
+ goto exit_device_unregister;
+ }
+
+ err = platform_device_add_data(pdev[i], &sio_data,
+ sizeof(struct nct6775_sio_data));
+ if (err)
+ goto exit_device_put;
+
+ memset(&res, 0, sizeof(res));
+ res.name = DRVNAME;
+ res.start = address;
+ res.end = address + IOREGION_LENGTH - 1;
+ res.flags = IORESOURCE_IO;
+
+ err = acpi_check_resource_conflict(&res);
+ if (err) {
+ platform_device_put(pdev[i]);
+ pdev[i] = NULL;
+ continue;
+ }
+
+ err = platform_device_add_resources(pdev[i], &res, 1);
+ if (err)
+ goto exit_device_put;
+
+ /* platform_device_add calls probe() */
+ err = platform_device_add(pdev[i]);
+ if (err)
+ goto exit_device_put;
+ }
+ if (!found) {
+ err = -ENODEV;
+ goto exit_unregister;
+ }
+
+ return 0;
+
+exit_device_put:
+ platform_device_put(pdev[i]);
+exit_device_unregister:
+ while (--i >= 0) {
+ if (pdev[i])
+ platform_device_unregister(pdev[i]);
+ }
+exit_unregister:
+ platform_driver_unregister(&i2c_nct6775_driver);
+ return err;
+}
+
+MODULE_AUTHOR("Adam Honse <calcprogrammer1@gmail.com>");
+MODULE_DESCRIPTION("SMBus driver for NCT6775F and compatible chips");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_nct6775_init);
+module_exit(i2c_nct6775_exit);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 809fbd014..d54b35b14 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -568,11 +568,11 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter)
if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
usleep_range(2000, 2100);
else
- usleep_range(250, 500);
+ usleep_range(25, 50);
while ((++timeout < MAX_TIMEOUT) &&
((temp = inb_p(SMBHSTSTS)) & 0x01))
- usleep_range(250, 500);
+ usleep_range(25, 50);
/* If the SMBus is still busy, we give up */
if (timeout == MAX_TIMEOUT) {
--
2.41.0

View File

@ -1,10 +1,22 @@
diff '--color=auto' -uraN cachyos/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c cachyos-amdgpu/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
--- cachyos/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 2023-10-30 05:31:08.000000000 +0300 From: Jan200101 <sentrycraft123@gmail.com>
+++ cachyos-amdgpu/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 2023-11-04 18:03:47.475158392 +0300 Date: Mon, 27 Nov 2023 09:53:59 +0100
@@ -582,15 +582,11 @@ Subject: [PATCH] drm/amdgpu: enable SI and CIK support by default
Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 10 ----------
drivers/gpu/drm/radeon/radeon_drv.c | 10 ++++++++++
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 81edf66dbea8..5021d03089ff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -582,13 +582,8 @@ module_param_named(timeout_period, amdgpu_watchdog_timer.period, uint, 0644);
*/ */
#ifdef CONFIG_DRM_AMDGPU_SI #ifdef CONFIG_DRM_AMDGPU_SI
-#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE) -#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE)
-int amdgpu_si_support = 0; -int amdgpu_si_support = 0;
-MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))"); -MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))");
@ -12,16 +24,13 @@ diff '--color=auto' -uraN cachyos/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c cachyo
int amdgpu_si_support = 1; int amdgpu_si_support = 1;
MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)"); MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)");
-#endif -#endif
module_param_named(si_support, amdgpu_si_support, int, 0444); module_param_named(si_support, amdgpu_si_support, int, 0444);
+
#endif #endif
@@ -601,13 +596,8 @@ module_param_named(si_support, amdgpu_si_support, int, 0444);
/**
@@ -601,15 +597,11 @@
*/ */
#ifdef CONFIG_DRM_AMDGPU_CIK #ifdef CONFIG_DRM_AMDGPU_CIK
-#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE) -#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE)
-int amdgpu_cik_support = 0; -int amdgpu_cik_support = 0;
-MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))"); -MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))");
@ -29,19 +38,17 @@ diff '--color=auto' -uraN cachyos/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c cachyo
int amdgpu_cik_support = 1; int amdgpu_cik_support = 1;
MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)"); MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)");
-#endif -#endif
module_param_named(cik_support, amdgpu_cik_support, int, 0444); module_param_named(cik_support, amdgpu_cik_support, int, 0444);
+
#endif #endif
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
/** index 7bf08164140e..865f186f48c4 100644
diff '--color=auto' -uraN cachyos/drivers/gpu/drm/radeon/radeon_drv.c cachyos-amdgpu/drivers/gpu/drm/radeon/radeon_drv.c --- a/drivers/gpu/drm/radeon/radeon_drv.c
--- cachyos/drivers/gpu/drm/radeon/radeon_drv.c 2023-10-30 05:31:08.000000000 +0300 +++ b/drivers/gpu/drm/radeon/radeon_drv.c
+++ cachyos-amdgpu/drivers/gpu/drm/radeon/radeon_drv.c 2023-11-04 18:00:50.099902000 +0300 @@ -239,12 +239,22 @@ module_param_named(uvd, radeon_uvd, int, 0444);
@@ -239,12 +239,22 @@
MODULE_PARM_DESC(vce, "vce enable/disable vce support (1 = enable, 0 = disable)"); MODULE_PARM_DESC(vce, "vce enable/disable vce support (1 = enable, 0 = disable)");
module_param_named(vce, radeon_vce, int, 0444); module_param_named(vce, radeon_vce, int, 0444);
+#ifdef CONFIG_DRM_AMDGPU_SI +#ifdef CONFIG_DRM_AMDGPU_SI
+int radeon_si_support = 0; +int radeon_si_support = 0;
+MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))"); +MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))");
@ -50,7 +57,7 @@ diff '--color=auto' -uraN cachyos/drivers/gpu/drm/radeon/radeon_drv.c cachyos-am
MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)"); MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)");
+#endif +#endif
module_param_named(si_support, radeon_si_support, int, 0444); module_param_named(si_support, radeon_si_support, int, 0444);
+#ifdef CONFIG_DRM_AMDGPU_CIK +#ifdef CONFIG_DRM_AMDGPU_CIK
+int radeon_cik_support = 0; +int radeon_cik_support = 0;
+MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))"); +MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))");
@ -59,5 +66,5 @@ diff '--color=auto' -uraN cachyos/drivers/gpu/drm/radeon/radeon_drv.c cachyos-am
MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)"); MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)");
+#endif +#endif
module_param_named(cik_support, radeon_cik_support, int, 0444); module_param_named(cik_support, radeon_cik_support, int, 0444);
static struct pci_device_id pciidlist[] = { static struct pci_device_id pciidlist[] = {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan200101 <sentrycraft123@gmail.com>
Date: Mon, 27 Nov 2023 15:25:48 +0100
Subject: [PATCH] mt76: mt7921: Disable powersave features by default
This brings WiFi latency down considerably and makes latency consistent by
disabling runtime PM and typical powersave features by default. The actual
power consumption difference is inconsequential on desktops and laptops,
while the performance difference is monumental. Latencies of 20+ ms are no
longer observed after this change, and the connection is much more stable.
Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
drivers/net/wireless/mediatek/mt76/mt7921/init.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index ff63f37f67d9..840b4c606c83 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -220,12 +220,6 @@ int mt7921_register_device(struct mt792x_dev *dev)
dev->pm.idle_timeout = MT792x_PM_TIMEOUT;
dev->pm.stats.last_wake_event = jiffies;
dev->pm.stats.last_doze_event = jiffies;
- if (!mt76_is_usb(&dev->mt76)) {
- dev->pm.enable_user = true;
- dev->pm.enable = true;
- dev->pm.ds_enable_user = true;
- dev->pm.ds_enable = true;
- }
if (!mt76_is_mmio(&dev->mt76))
hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;
@@ -240,6 +234,8 @@ int mt7921_register_device(struct mt792x_dev *dev)
if (ret)
return ret;
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
hw->wiphy->reg_notifier = mt7921_regd_notifier;
dev->mphy.sband_2g.sband.ht_cap.cap |=
IEEE80211_HT_CAP_LDPC_CODING |

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +0,0 @@
From df561bb39dc0ae974bbd1d0f88b8a75cc8c20b7c Mon Sep 17 00:00:00 2001
From: GloriousEggroll <gloriouseggroll@gmail.com>
Date: Wed, 30 Aug 2023 20:25:07 -0600
Subject: [PATCH 09/18] rog-ally-side-keys
---
drivers/hid/hid-asus.c | 8 ++++++++
drivers/hid/hid-ids.h | 1 +
2 files changed, 9 insertions(+)
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index fd61dba88..596196c04 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -899,6 +899,11 @@ static int asus_input_mapping(struct hid_device *hdev,
case 0x4b: asus_map_key_clear(KEY_F14); break; /* Arrows/Pg-Up/Dn toggle */
+ case 0xa5: asus_map_key_clear(KEY_F15); break; /* ROG Ally left back */
+ case 0xa6: asus_map_key_clear(KEY_F16); break; /* ROG Ally QAM button */
+ case 0xa7: asus_map_key_clear(KEY_F17); break; /* ROG Ally ROG long-press */
+ case 0xa8: asus_map_key_clear(KEY_F18); break; /* ROG Ally ROG longer-press */
+
default:
/* ASUS lazily declares 256 usages, ignore the rest,
* as some make the keyboard appear as a pointer device. */
@@ -1252,6 +1257,9 @@ static const struct hid_device_id asus_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD),
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+ USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY),
+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2),
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 8a310f8ff..46f5262d7 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -208,6 +208,7 @@
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe
#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
--
2.41.0

File diff suppressed because it is too large Load Diff

133
patches/nobara/uinput.patch Normal file
View File

@ -0,0 +1,133 @@
---
drivers/input/misc/uinput.c | 48 +++++++++++++++++++++++++------------
include/uapi/linux/uinput.h | 5 ++++
2 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 84051f20b18a..2c3180370a02 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -20,6 +20,7 @@
*/
#include <uapi/linux/uinput.h>
#include <linux/poll.h>
+#include <linux/printk.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -280,7 +281,7 @@ static int uinput_dev_flush(struct input_dev *dev, struct file *file)
static void uinput_destroy_device(struct uinput_device *udev)
{
- const char *name, *phys;
+ const char *name, *phys, *uniq;
struct input_dev *dev = udev->dev;
enum uinput_state old_state = udev->state;
@@ -289,6 +290,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
if (dev) {
name = dev->name;
phys = dev->phys;
+ uniq = dev->uniq;
if (old_state == UIST_CREATED) {
uinput_flush_requests(udev);
input_unregister_device(dev);
@@ -297,6 +299,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
}
kfree(name);
kfree(phys);
+ kfree(uniq);
udev->dev = NULL;
}
}
@@ -831,6 +834,24 @@ static int uinput_str_to_user(void __user *dest, const char *str,
return ret ? -EFAULT : len;
}
+static int uinput_get_user_str(struct uinput_device *udev, const char **kptr,
+ const char *uptr, unsigned int size)
+{
+ char *tmp;
+
+ if (udev->state == UIST_CREATED)
+ return -EINVAL;
+
+ tmp = strndup_user(uptr, size);
+ if (IS_ERR(tmp))
+ return PTR_ERR(tmp);
+
+ kfree(*kptr);
+ *kptr = tmp;
+
+ return 0;
+}
+
static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
unsigned long arg, void __user *p)
{
@@ -839,7 +860,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
struct uinput_ff_upload ff_up;
struct uinput_ff_erase ff_erase;
struct uinput_request *req;
- char *phys;
const char *name;
unsigned int size;
@@ -916,19 +936,8 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
goto out;
case UI_SET_PHYS:
- if (udev->state == UIST_CREATED) {
- retval = -EINVAL;
- goto out;
- }
-
- phys = strndup_user(p, 1024);
- if (IS_ERR(phys)) {
- retval = PTR_ERR(phys);
- goto out;
- }
-
- kfree(udev->dev->phys);
- udev->dev->phys = phys;
+ pr_warn_once("uinput: UI_SET_PHYS is deprecated. Use UI_SET_PHYS_STR");
+ retval = uinput_get_user_str(udev, &udev->dev->phys, p, 1024);
goto out;
case UI_BEGIN_FF_UPLOAD:
@@ -1023,6 +1032,15 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
case UI_ABS_SETUP & ~IOCSIZE_MASK:
retval = uinput_abs_setup(udev, p, size);
goto out;
+
+ case UI_SET_PHYS_STR(0):
+ retval = uinput_get_user_str(udev, &udev->dev->phys, p, size);
+ goto out;
+
+ case UI_SET_UNIQ_STR(0):
+ retval = uinput_get_user_str(udev, &udev->dev->uniq, p, size);
+ goto out;
+
}
retval = -EINVAL;
diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h
index c9e677e3af1d..84d4fa142830 100644
--- a/include/uapi/linux/uinput.h
+++ b/include/uapi/linux/uinput.h
@@ -142,9 +142,14 @@ struct uinput_abs_setup {
#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
+
+/* DEPRECATED: Data size is ambiguous. Use UI_SET_PHYS_STR instead. */
#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
+
#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
+#define UI_SET_PHYS_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 111, len)
+#define UI_SET_UNIQ_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 112, len)
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,26 @@
cachyos/0001-cachyos-base-all.patch cachyos/0001-cachyos-base-all.patch
cachyos/0001-bore-cachy.patch cachyos/0001-bore-cachy.patch
asuslinux/ROG-ALLY-NCT6775-PLATFORM.patch
asuslinux/asus-linux.patch
asuslinux/rog-ally-audio-fix.patch
asuslinux/rog-ally-bmc150.patch
asuslinux/v2-0001-platform-x86-asus-wmi-disable-USB0-hub-on-ROG-All.patch
nobara/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch nobara/0001-Allow-to-set-custom-USB-pollrate-for-specific-device.patch
nobara/set-ps4-bt-poll-rate-1000hz.patch
nobara-rebased/amdgpu-si-cik-default.patch
nobara/0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch nobara/0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch
#nobara/0001-Revert-nvme-pci-drop-redundant-pci_enable_pcie_error.patch nobara/0001-Revert-nvme-pci-drop-redundant-pci_enable_pcie_error.patch
nobara/0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch
nobara/0001-acpi-proc-idle-skip-dummy-wait.patch nobara/0001-acpi-proc-idle-skip-dummy-wait.patch
nobara/0001-add-acpi_call.patch
nobara/0001-amd-hdr.patch
nobara/0001-drm-i915-quirks-disable-async-flipping-on-specific-d.patch nobara/0001-drm-i915-quirks-disable-async-flipping-on-specific-d.patch
nobara/0001-hid-asus-nero-patches-rogue.patch
nobara/0002-drm-i915-add-kernel-parameter-to-disable-async-page-.patch nobara/0002-drm-i915-add-kernel-parameter-to-disable-async-page-.patch
asuslinux/v6-0001-platform-x86-asus-wmi-add-support-for-ASUS-screen.patch nobara/OpenRGB.patch
asuslinux-rebased/v2-0002-ALSA-hda-cs35l41-Support-ASUS-2023-laptops-with-m.patch nobara/amdgpu-si-cik-default.patch
asuslinux/amd-tablet-sfh.patch nobara/lenovo-legion-laptop.patch
#nobara-rebased/linux-surface.patch nobara/linux-surface.patch
nobara/rog-ally-bmc150.patch nobara/mt76:-mt7921:-Disable-powersave-features-by-default.patch
nobara/rog-ally-side-keys-fix.patch nobara/set-ps4-bt-poll-rate-1000hz.patch
nobara/rog-ally-alsa.patch nobara/steam-deck.patch
nobara/uinput.patch
nobara/winesync.patc