diff --git a/packages/b/bbswitch/package.yml b/packages/b/bbswitch/package.yml
index 17344e362b5..edb5b3b4feb 100644
--- a/packages/b/bbswitch/package.yml
+++ b/packages/b/bbswitch/package.yml
@@ -1,6 +1,6 @@
name : bbswitch
version : '0.8'
-release : 350
+release : 351
source :
- https://github.com/Bumblebee-Project/bbswitch/archive/v0.8.tar.gz : 76cabd3f734fb4fe6ebfe3ec9814138d0d6f47d47238521ecbd6a986b60d1477
license : GPL-2.0-or-later
diff --git a/packages/b/bbswitch/pspec_x86_64.xml b/packages/b/bbswitch/pspec_x86_64.xml
index 057113974d2..9c5c1a38521 100644
--- a/packages/b/bbswitch/pspec_x86_64.xml
+++ b/packages/b/bbswitch/pspec_x86_64.xml
@@ -20,8 +20,8 @@
kernel.drivers
- /lib64/modules/6.6.63-261.lts/misc/bbswitch.ko.zst
- /usr/lib64/modules/6.6.63-261.lts/misc/bbswitch.ko.zst
+ /lib64/modules/6.6.66-262.lts/misc/bbswitch.ko.zst
+ /usr/lib64/modules/6.6.66-262.lts/misc/bbswitch.ko.zst
@@ -31,13 +31,13 @@
kernel.drivers
- /lib64/modules/6.11.10-310.current/misc/bbswitch.ko.zst
- /usr/lib64/modules/6.11.10-310.current/misc/bbswitch.ko.zst
+ /lib64/modules/6.12.5-311.current/misc/bbswitch.ko.zst
+ /usr/lib64/modules/6.12.5-311.current/misc/bbswitch.ko.zst
-
- 2024-11-23
+
+ 2024-12-18
0.8
Packaging update
Reilly Brogan
diff --git a/packages/b/broadcom-sta/files/linux-6.12.patch b/packages/b/broadcom-sta/files/linux-6.12.patch
new file mode 100644
index 00000000000..b7d9ef68554
--- /dev/null
+++ b/packages/b/broadcom-sta/files/linux-6.12.patch
@@ -0,0 +1,15 @@
+diff -Nurp a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c
+--- a/src/wl/sys/wl_linux.c 2024-11-19 03:05:21.160736778 +0000
++++ b/src/wl/sys/wl_linux.c 2024-11-19 03:09:59.010905106 +0000
+@@ -56,7 +56,11 @@
+ #include
+ #include
+ #include
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
++#include
++#else
+ #include
++#endif
+
+ #include
+
diff --git a/packages/b/broadcom-sta/files/series b/packages/b/broadcom-sta/files/series
index cd11fb87378..a8505f6d174 100644
--- a/packages/b/broadcom-sta/files/series
+++ b/packages/b/broadcom-sta/files/series
@@ -24,3 +24,4 @@ debian/26-linux-5.18.patch
debian/27-linux-6.00.patch
debian/28-wl-Update-for-linux-5.17-deprecations.patch
debian/29-linux-6.01.patch
+linux-6.12.patch
diff --git a/packages/b/broadcom-sta/package.yml b/packages/b/broadcom-sta/package.yml
index 0fe633bfd36..44ea4e31236 100644
--- a/packages/b/broadcom-sta/package.yml
+++ b/packages/b/broadcom-sta/package.yml
@@ -1,6 +1,6 @@
name : broadcom-sta
version : 6.30.223.271
-release : 420
+release : 421
homepage : http://www.broadcom.com/support/802.11/linux_sta.php
source :
- https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz : 5f79774d5beec8f7636b59c0fb07a03108eef1e3fd3245638b20858c714144be
diff --git a/packages/b/broadcom-sta/pspec_x86_64.xml b/packages/b/broadcom-sta/pspec_x86_64.xml
index f9c96041965..852f2c5070f 100644
--- a/packages/b/broadcom-sta/pspec_x86_64.xml
+++ b/packages/b/broadcom-sta/pspec_x86_64.xml
@@ -20,11 +20,11 @@
kernel.drivers
- broadcom-sta-common
+ broadcom-sta-common
- /lib64/modules/6.6.63-261.lts/kernel/drivers/net/wireless/wl.ko.zst
- /usr/lib64/modules/6.6.63-261.lts/kernel/drivers/net/wireless/wl.ko.zst
+ /lib64/modules/6.6.66-262.lts/kernel/drivers/net/wireless/wl.ko.zst
+ /usr/lib64/modules/6.6.66-262.lts/kernel/drivers/net/wireless/wl.ko.zst
/usr/share/metainfo/broadcom-sta-lts.metainfo.xml
@@ -45,11 +45,11 @@
kernel.drivers
- broadcom-sta-common
+ broadcom-sta-common
- /lib64/modules/6.11.10-310.current/kernel/drivers/net/wireless/wl.ko.zst
- /usr/lib64/modules/6.11.10-310.current/kernel/drivers/net/wireless/wl.ko.zst
+ /lib64/modules/6.12.5-311.current/kernel/drivers/net/wireless/wl.ko.zst
+ /usr/lib64/modules/6.12.5-311.current/kernel/drivers/net/wireless/wl.ko.zst
/usr/share/metainfo/broadcom-sta-current.metainfo.xml
@@ -64,8 +64,8 @@
-
- 2024-11-23
+
+ 2024-12-18
6.30.223.271
Packaging update
Reilly Brogan
diff --git a/packages/l/linux-current/files/config b/packages/l/linux-current/files/config
index 0eb2c33b92b..af5364c5f2d 100644
--- a/packages/l/linux-current/files/config
+++ b/packages/l/linux-current/files/config
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/x86 6.11.10 Kernel Configuration
+# Linux/x86 6.12.5 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (Solus) 14.2.0"
CONFIG_CC_IS_GCC=y
@@ -11,6 +11,8 @@ CONFIG_AS_VERSION=24301
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=24301
CONFIG_LLD_VERSION=0
+CONFIG_RUSTC_VERSION=108300
+CONFIG_RUSTC_LLVM_VERSION=190105
CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
@@ -85,7 +87,6 @@ CONFIG_SPARSE_IRQ=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_INIT=y
-CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
@@ -136,6 +137,7 @@ CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y
CONFIG_PREEMPT_DYNAMIC=y
CONFIG_SCHED_CORE=y
+CONFIG_SCHED_CLASS_EXT=y
#
# CPU/Task time and stats accounting
@@ -218,9 +220,11 @@ CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
+CONFIG_GROUP_SCHED_WEIGHT=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_EXT_GROUP_SCHED=y
CONFIG_SCHED_MM_CID=y
CONFIG_UCLAMP_TASK_GROUP=y
CONFIG_CGROUP_PIDS=y
@@ -228,6 +232,7 @@ CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CPUSETS=y
+# CONFIG_CPUSETS_V1 is not set
CONFIG_PROC_PID_CPUSET=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
@@ -449,7 +454,6 @@ CONFIG_X86_DIRECT_GBPAGES=y
CONFIG_NUMA=y
CONFIG_AMD_NUMA=y
CONFIG_X86_64_ACPI_NUMA=y
-# CONFIG_NUMA_EMU is not set
CONFIG_NODES_SHIFT=2
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
@@ -463,12 +467,12 @@ CONFIG_MTRR_SANITIZER=y
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
CONFIG_X86_PAT=y
-CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_X86_UMIP=y
CONFIG_CC_HAS_IBT=y
CONFIG_X86_CET=y
# CONFIG_X86_KERNEL_IBT is not set
CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
+CONFIG_ARCH_PKEY_BITS=4
CONFIG_X86_INTEL_TSX_MODE_OFF=y
# CONFIG_X86_INTEL_TSX_MODE_ON is not set
# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set
@@ -534,9 +538,18 @@ CONFIG_MITIGATION_IBPB_ENTRY=y
CONFIG_MITIGATION_IBRS_ENTRY=y
CONFIG_MITIGATION_SRSO=y
CONFIG_MITIGATION_SLS=y
-# CONFIG_MITIGATION_GDS_FORCE is not set
+CONFIG_MITIGATION_GDS=y
CONFIG_MITIGATION_RFDS=y
CONFIG_MITIGATION_SPECTRE_BHI=y
+CONFIG_MITIGATION_MDS=y
+CONFIG_MITIGATION_TAA=y
+CONFIG_MITIGATION_MMIO_STALE_DATA=y
+CONFIG_MITIGATION_L1TF=y
+CONFIG_MITIGATION_RETBLEED=y
+CONFIG_MITIGATION_SPECTRE_V1=y
+CONFIG_MITIGATION_SPECTRE_V2=y
+CONFIG_MITIGATION_SRBDS=y
+CONFIG_MITIGATION_SSB=y
CONFIG_ARCH_HAS_ADD_PAGES=y
#
@@ -731,6 +744,7 @@ CONFIG_HAVE_KVM_PM_NOTIFIER=y
CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y
CONFIG_KVM_GENERIC_MMU_NOTIFIER=y
CONFIG_VIRTUALIZATION=y
+CONFIG_KVM_X86=m
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_X86_SGX_KVM=y
@@ -750,6 +764,7 @@ CONFIG_AS_VAES=y
CONFIG_AS_VPCLMULQDQ=y
CONFIG_AS_WRUSS=y
CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y
+CONFIG_ARCH_HAS_DMA_OPS=y
#
# General architecture-dependent options
@@ -813,6 +828,7 @@ CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
CONFIG_MMU_GATHER_MERGE_VMAS=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
+CONFIG_ARCH_HAVE_EXTRA_ELF_NOTES=y
CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
@@ -874,6 +890,7 @@ CONFIG_ISA_BUS_API=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_COMPAT_OLD_SIGACTION=y
CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_ARCH_SUPPORTS_RT=y
CONFIG_HAVE_ARCH_VMAP_STACK=y
CONFIG_VMAP_STACK=y
CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y
@@ -931,10 +948,11 @@ CONFIG_MODVERSIONS=y
CONFIG_ASM_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_MODULE_SIG is not set
-# CONFIG_MODULE_COMPRESS_NONE is not set
+CONFIG_MODULE_COMPRESS=y
# CONFIG_MODULE_COMPRESS_GZIP is not set
# CONFIG_MODULE_COMPRESS_XZ is not set
CONFIG_MODULE_COMPRESS_ZSTD=y
+# CONFIG_MODULE_COMPRESS_ALL is not set
CONFIG_MODULE_DECOMPRESS=y
# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
CONFIG_MODPROBE_PATH="/usr/sbin/modprobe"
@@ -1060,7 +1078,6 @@ CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC=y
CONFIG_ZSWAP_ZPOOL_DEFAULT="zsmalloc"
# CONFIG_ZBUD is not set
# CONFIG_Z3FOLD_DEPRECATED is not set
-CONFIG_HAVE_ZSMALLOC=y
CONFIG_ZSMALLOC=y
# CONFIG_ZSMALLOC_STAT is not set
CONFIG_ZSMALLOC_CHAIN_SIZE=8
@@ -1098,8 +1115,9 @@ CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_MHP_MEMMAP_ON_MEMORY=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTE_PTLOCKS=y
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
+CONFIG_SPLIT_PMD_PTLOCKS=y
CONFIG_MEMORY_BALLOON=y
CONFIG_BALLOON_COMPACTION=y
CONFIG_COMPACTION=y
@@ -1126,6 +1144,9 @@ CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
CONFIG_THP_SWAP=y
# CONFIG_READ_ONLY_THP_FOR_FS is not set
CONFIG_PGTABLE_HAS_HUGE_LEAVES=y
+CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP=y
+CONFIG_ARCH_SUPPORTS_PMD_PFNMAP=y
+CONFIG_ARCH_SUPPORTS_PUD_PFNMAP=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_USE_PERCPU_NUMA_NODE_ID=y
@@ -1147,6 +1168,7 @@ CONFIG_DEVICE_PRIVATE=y
CONFIG_VMAP_PFN=y
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
CONFIG_ARCH_HAS_PKEYS=y
+CONFIG_ARCH_USES_PG_ARCH_2=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PERCPU_STATS=y
# CONFIG_GUP_TEST is not set
@@ -1169,6 +1191,8 @@ CONFIG_PER_VMA_LOCK=y
CONFIG_LOCK_MM_AND_FIND_VMA=y
CONFIG_IOMMU_MM_DATA=y
CONFIG_EXECMEM=y
+CONFIG_NUMA_MEMBLKS=y
+# CONFIG_NUMA_EMU is not set
#
# Data Access Monitoring
@@ -1185,6 +1209,7 @@ CONFIG_NET_XGRESS=y
CONFIG_NET_REDIRECT=y
CONFIG_SKB_DECRYPTED=y
CONFIG_SKB_EXTENSIONS=y
+CONFIG_NET_DEVMEM=y
#
# Networking options
@@ -1900,7 +1925,6 @@ CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_CMTP=m
CONFIG_BT_HIDP=m
CONFIG_BT_LE=y
CONFIG_BT_LE_L2CAP_ECRED=y
@@ -1940,6 +1964,7 @@ CONFIG_BT_HCIUART_RTL=y
CONFIG_BT_HCIUART_QCA=y
CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_HCIUART_AML=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBCM4377=m
CONFIG_BT_HCIBPA10X=m
@@ -2058,6 +2083,7 @@ CONFIG_PCI_STUB=m
CONFIG_PCI_ATS=y
CONFIG_PCI_LOCKLESS_CONFIG=y
CONFIG_PCI_IOV=y
+CONFIG_PCI_NPEM=y
CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
CONFIG_PCI_P2PDMA=y
@@ -2439,11 +2465,13 @@ CONFIG_BLK_DEV=y
CONFIG_CDROM=m
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
CONFIG_ZRAM=m
-# CONFIG_ZRAM_DEF_COMP_LZORLE is not set
+# CONFIG_ZRAM_BACKEND_LZ4 is not set
+# CONFIG_ZRAM_BACKEND_LZ4HC is not set
+CONFIG_ZRAM_BACKEND_ZSTD=y
+# CONFIG_ZRAM_BACKEND_DEFLATE is not set
+# CONFIG_ZRAM_BACKEND_842 is not set
+# CONFIG_ZRAM_BACKEND_LZO is not set
CONFIG_ZRAM_DEF_COMP_ZSTD=y
-# CONFIG_ZRAM_DEF_COMP_LZ4 is not set
-# CONFIG_ZRAM_DEF_COMP_LZO is not set
-# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set
CONFIG_ZRAM_DEF_COMP="zstd"
CONFIG_ZRAM_WRITEBACK=y
CONFIG_ZRAM_TRACK_ENTRY_ACTIME=y
@@ -2497,6 +2525,7 @@ CONFIG_SENSORS_LIS3LV02D=m
CONFIG_DUMMY_IRQ=m
CONFIG_IBM_ASM=m
CONFIG_PHANTOM=m
+CONFIG_RPMB=m
CONFIG_TIFM_CORE=m
CONFIG_TIFM_7XX1=m
CONFIG_ICS932S401=m
@@ -3125,6 +3154,7 @@ CONFIG_ENC28J60=m
# CONFIG_ENC28J60_WRITEVERIFY is not set
# CONFIG_ENCX24J600 is not set
# CONFIG_LAN743X is not set
+# CONFIG_LAN865X is not set
# CONFIG_VCAP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
CONFIG_NET_VENDOR_MICROSOFT=y
@@ -3147,6 +3177,7 @@ CONFIG_NET_VENDOR_NVIDIA=y
CONFIG_FORCEDETH=m
CONFIG_NET_VENDOR_OKI=y
CONFIG_ETHOC=m
+CONFIG_OA_TC6=m
# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
# CONFIG_NET_VENDOR_PENSANDO is not set
CONFIG_NET_VENDOR_QLOGIC=y
@@ -3173,6 +3204,7 @@ CONFIG_8139TOO_TUNE_TWISTER=y
CONFIG_8139TOO_8129=y
# CONFIG_8139_OLD_RX_RESET is not set
CONFIG_R8169=m
+# CONFIG_RTASE is not set
# CONFIG_NET_VENDOR_RENESAS is not set
CONFIG_NET_VENDOR_ROCKER=y
CONFIG_NET_VENDOR_SAMSUNG=y
@@ -3719,11 +3751,13 @@ CONFIG_RTW89_8851B=m
CONFIG_RTW89_8852A=m
CONFIG_RTW89_8852B_COMMON=m
CONFIG_RTW89_8852B=m
+CONFIG_RTW89_8852BT=m
CONFIG_RTW89_8852C=m
CONFIG_RTW89_8922A=m
CONFIG_RTW89_8851BE=m
CONFIG_RTW89_8852AE=m
CONFIG_RTW89_8852BE=m
+CONFIG_RTW89_8852BTE=m
CONFIG_RTW89_8852CE=m
CONFIG_RTW89_8922AE=m
# CONFIG_RTW89_DEBUGMSG is not set
@@ -3783,8 +3817,6 @@ CONFIG_HYPERV_NET=m
CONFIG_NET_FAILOVER=m
CONFIG_ISDN=y
CONFIG_ISDN_CAPI=y
-CONFIG_CAPI_TRACE=y
-CONFIG_ISDN_CAPI_MIDDLEWARE=y
CONFIG_MISDN=m
CONFIG_MISDN_DSP=m
CONFIG_MISDN_L1OIP=m
@@ -3846,7 +3878,6 @@ CONFIG_KEYBOARD_MATRIX=m
CONFIG_KEYBOARD_LM8323=m
CONFIG_KEYBOARD_LM8333=m
CONFIG_KEYBOARD_MAX7359=m
-CONFIG_KEYBOARD_MCS=m
CONFIG_KEYBOARD_MPR121=m
CONFIG_KEYBOARD_NEWTON=m
CONFIG_KEYBOARD_OPENCORES=m
@@ -3950,9 +3981,6 @@ CONFIG_TOUCHSCREEN_CY8CTMG110=m
CONFIG_TOUCHSCREEN_CYTTSP_CORE=m
CONFIG_TOUCHSCREEN_CYTTSP_I2C=m
CONFIG_TOUCHSCREEN_CYTTSP_SPI=m
-CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m
-CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m
-CONFIG_TOUCHSCREEN_CYTTSP4_SPI=m
CONFIG_TOUCHSCREEN_CYTTSP5=m
CONFIG_TOUCHSCREEN_DYNAPRO=m
CONFIG_TOUCHSCREEN_HAMPSHIRE=m
@@ -3977,7 +4005,6 @@ CONFIG_TOUCHSCREEN_ELO=m
CONFIG_TOUCHSCREEN_WACOM_W8001=m
CONFIG_TOUCHSCREEN_WACOM_I2C=m
CONFIG_TOUCHSCREEN_MAX11801=m
-CONFIG_TOUCHSCREEN_MCS5000=m
CONFIG_TOUCHSCREEN_MMS114=m
CONFIG_TOUCHSCREEN_MELFAS_MIP4=m
CONFIG_TOUCHSCREEN_MSG2638=m
@@ -4264,7 +4291,6 @@ CONFIG_TELCLOCK=m
CONFIG_I2C=y
CONFIG_ACPI_I2C_OPREGION=y
CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_MUX=m
@@ -4657,7 +4683,6 @@ CONFIG_W1_SLAVE_DS2433=m
# CONFIG_POWER_RESET is not set
CONFIG_POWER_SEQUENCING=m
-CONFIG_POWER_SEQUENCING_QCOM_WCN=m
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_POWER_SUPPLY_HWMON=y
@@ -4927,6 +4952,7 @@ CONFIG_THERMAL=y
CONFIG_THERMAL_NETLINK=y
# CONFIG_THERMAL_STATISTICS is not set
# CONFIG_THERMAL_DEBUGFS is not set
+CONFIG_THERMAL_CORE_TESTING=m
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
@@ -5291,6 +5317,7 @@ CONFIG_CEC_CROS_EC=m
CONFIG_CEC_GPIO=m
CONFIG_CEC_SECO=m
CONFIG_CEC_SECO_RC=y
+CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC=m
CONFIG_USB_PULSE8_CEC=m
CONFIG_USB_RAINSHADOW_CEC=m
# end of CEC support
@@ -6152,6 +6179,11 @@ CONFIG_DRM=m
CONFIG_DRM_MIPI_DSI=y
# CONFIG_DRM_DEBUG_MM is not set
CONFIG_DRM_KMS_HELPER=m
+CONFIG_DRM_PANIC=y
+CONFIG_DRM_PANIC_FOREGROUND_COLOR=0xffffff
+CONFIG_DRM_PANIC_BACKGROUND_COLOR=0x000000
+# CONFIG_DRM_PANIC_DEBUG is not set
+CONFIG_DRM_PANIC_SCREEN="kmsg"
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
@@ -6334,6 +6366,7 @@ CONFIG_FB_EFI=y
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
@@ -6460,7 +6493,6 @@ CONFIG_SND_MAX_CARDS=32
# CONFIG_SND_SUPPORT_OLD_API is not set
CONFIG_SND_PROC_FS=y
CONFIG_SND_VERBOSE_PROCFS=y
-CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_CTL_FAST_LOOKUP=y
CONFIG_SND_DEBUG=y
# CONFIG_SND_DEBUG_VERBOSE is not set
@@ -6468,6 +6500,7 @@ CONFIG_SND_DEBUG=y
CONFIG_SND_CTL_INPUT_VALIDATION=y
# CONFIG_SND_CTL_DEBUG is not set
# CONFIG_SND_JACK_INJECTION_DEBUG is not set
+CONFIG_SND_UTIMER=y
CONFIG_SND_VMASTER=y
CONFIG_SND_DMA_SGBUF=y
CONFIG_SND_CTL_LED=m
@@ -6680,6 +6713,7 @@ CONFIG_SND_SOC_AMD_ACP6x=m
CONFIG_SND_SOC_AMD_YC_MACH=m
CONFIG_SND_AMD_ACP_CONFIG=m
CONFIG_SND_SOC_AMD_ACP_COMMON=m
+CONFIG_SND_SOC_ACPI_AMD_MATCH=m
CONFIG_SND_SOC_AMD_ACP_PDM=m
CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON=m
CONFIG_SND_SOC_AMD_ACP_I2S=m
@@ -6692,6 +6726,7 @@ CONFIG_SND_AMD_ASOC_ACP70=m
CONFIG_SND_SOC_AMD_MACH_COMMON=m
CONFIG_SND_SOC_AMD_LEGACY_MACH=m
CONFIG_SND_SOC_AMD_SOF_MACH=m
+CONFIG_SND_SOC_AMD_SOF_SDW_MACH=m
CONFIG_SND_AMD_SOUNDWIRE_ACPI=m
CONFIG_SND_SOC_AMD_RPL_ACP6x=m
CONFIG_SND_SOC_AMD_ACP63_TOPLEVEL=m
@@ -6733,24 +6768,10 @@ CONFIG_SND_SOC_IMG_SPDIF_IN=m
CONFIG_SND_SOC_IMG_SPDIF_OUT=m
CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=m
CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
-CONFIG_SND_SOC_INTEL_SST=m
CONFIG_SND_SOC_INTEL_CATPT=m
CONFIG_SND_SST_ATOM_HIFI2_PLATFORM=m
CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI=m
CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI=m
-CONFIG_SND_SOC_INTEL_SKYLAKE=m
-CONFIG_SND_SOC_INTEL_SKL=m
-CONFIG_SND_SOC_INTEL_APL=m
-CONFIG_SND_SOC_INTEL_KBL=m
-CONFIG_SND_SOC_INTEL_GLK=m
-CONFIG_SND_SOC_INTEL_CNL=m
-CONFIG_SND_SOC_INTEL_CFL=m
-CONFIG_SND_SOC_INTEL_CML_H=m
-CONFIG_SND_SOC_INTEL_CML_LP=m
-CONFIG_SND_SOC_INTEL_SKYLAKE_FAMILY=m
-CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK=m
-CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC=y
-CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON=m
CONFIG_SND_SOC_ACPI_INTEL_MATCH=m
CONFIG_SND_SOC_INTEL_AVS=m
@@ -6803,18 +6824,7 @@ CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH=m
CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m
CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH=m
# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set
-CONFIG_SND_SOC_INTEL_SKL_RT286_MACH=m
-CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH=m
-CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH=m
-CONFIG_SND_SOC_INTEL_DA7219_MAX98357A_GENERIC=m
-CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH=m
-CONFIG_SND_SOC_INTEL_BXT_RT298_MACH=m
CONFIG_SND_SOC_INTEL_SOF_WM8804_MACH=m
-CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH=m
-CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH=m
-CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH=m
-CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH=m
-CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH=m
CONFIG_SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH=m
CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH=m
CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH=m
@@ -6850,6 +6860,7 @@ CONFIG_SND_SOC_SOF_ACP_PROBES=m
CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE_LINK_BASELINE=m
CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE=m
CONFIG_SND_SOC_SOF_AMD_ACP63=m
+CONFIG_SND_SOC_SOF_AMD_ACP70=m
CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y
CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC=m
CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP=m
@@ -6877,6 +6888,8 @@ CONFIG_SND_SOC_SOF_INTEL_MTL=m
CONFIG_SND_SOC_SOF_METEORLAKE=m
CONFIG_SND_SOC_SOF_INTEL_LNL=m
CONFIG_SND_SOC_SOF_LUNARLAKE=m
+CONFIG_SND_SOC_SOF_INTEL_PTL=m
+CONFIG_SND_SOC_SOF_PANTHERLAKE=m
CONFIG_SND_SOC_SOF_HDA_COMMON=m
CONFIG_SND_SOC_SOF_HDA_GENERIC=m
CONFIG_SND_SOC_SOF_HDA_MLINK=m
@@ -7000,7 +7013,6 @@ CONFIG_SND_SOC_ES8328=m
CONFIG_SND_SOC_ES8328_I2C=m
CONFIG_SND_SOC_ES8328_SPI=m
CONFIG_SND_SOC_GTM601=m
-CONFIG_SND_SOC_HDAC_HDMI=m
CONFIG_SND_SOC_HDAC_HDA=m
CONFIG_SND_SOC_HDA=m
CONFIG_SND_SOC_ICS43432=m
@@ -7058,7 +7070,6 @@ CONFIG_SND_SOC_RT1316_SDW=m
CONFIG_SND_SOC_RT1318_SDW=m
CONFIG_SND_SOC_RT1320_SDW=m
CONFIG_SND_SOC_RT5514=m
-CONFIG_SND_SOC_RT5514_SPI=m
CONFIG_SND_SOC_RT5616=m
CONFIG_SND_SOC_RT5631=m
CONFIG_SND_SOC_RT5640=m
@@ -7184,6 +7195,7 @@ CONFIG_SND_SOC_WSA884X=m
CONFIG_SND_SOC_ZL38060=m
CONFIG_SND_SOC_MAX9759=m
CONFIG_SND_SOC_MT6351=m
+CONFIG_SND_SOC_MT6357=m
CONFIG_SND_SOC_MT6358=m
CONFIG_SND_SOC_MT6660=m
CONFIG_SND_SOC_NAU8315=m
@@ -7201,6 +7213,7 @@ CONFIG_SND_SOC_LPASS_RX_MACRO=m
CONFIG_SND_SOC_LPASS_TX_MACRO=m
# end of CODEC drivers
+CONFIG_SND_SOC_SDW_UTILS=m
CONFIG_SND_SIMPLE_CARD_UTILS=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SND_X86=y
@@ -7254,6 +7267,7 @@ CONFIG_HID_GEMBIRD=m
CONFIG_HID_GLORIOUS=m
CONFIG_HID_HOLTEK=m
CONFIG_HOLTEK_FF=y
+CONFIG_HID_GOODIX_SPI=m
# CONFIG_HID_GOOGLE_HAMMER is not set
CONFIG_HID_GOOGLE_STADIA_FF=m
# CONFIG_HID_VIVALDI is not set
@@ -7901,6 +7915,7 @@ CONFIG_RTC_DRV_RX8025=m
# CONFIG_RTC_DRV_RV3028 is not set
# CONFIG_RTC_DRV_RV3032 is not set
# CONFIG_RTC_DRV_RV8803 is not set
+CONFIG_RTC_DRV_SD2405AL=m
# CONFIG_RTC_DRV_SD3078 is not set
#
@@ -7979,6 +7994,7 @@ CONFIG_INTEL_IOATDMA=m
# CONFIG_PLX_DMA is not set
# CONFIG_XILINX_DMA is not set
# CONFIG_XILINX_XDMA is not set
+CONFIG_AMD_QDMA=m
# CONFIG_AMD_PTDMA is not set
# CONFIG_QCOM_HIDMA_MGMT is not set
# CONFIG_QCOM_HIDMA is not set
@@ -8162,7 +8178,6 @@ CONFIG_VIDEO_IPU3_IMGU=m
#
# CONFIG_STAGING_MEDIA_DEPRECATED is not set
# CONFIG_LTE_GDM724X is not set
-# CONFIG_KS7010 is not set
# CONFIG_FIELDBUS_DEV is not set
# CONFIG_VME_BUS is not set
# CONFIG_GOLDFISH is not set
@@ -8238,7 +8253,7 @@ CONFIG_ASUS_LAPTOP=m
CONFIG_ASUS_WIRELESS=m
CONFIG_ASUS_ARMOURY=m
CONFIG_ASUS_WMI=m
-CONFIG_ASUS_WMI_BIOS=y
+CONFIG_ASUS_WMI_DEPRECATED_ATTRS=y
CONFIG_ASUS_NB_WMI=m
CONFIG_ASUS_TF103C_DOCK=m
# CONFIG_MERAKI_MX100 is not set
@@ -8554,6 +8569,7 @@ CONFIG_EXTCON=y
# CONFIG_EXTCON_GPIO is not set
# CONFIG_EXTCON_INTEL_INT3496 is not set
CONFIG_EXTCON_INTEL_MRFLD=m
+# CONFIG_EXTCON_LC824206XA is not set
# CONFIG_EXTCON_MAX3355 is not set
# CONFIG_EXTCON_PTN5150 is not set
# CONFIG_EXTCON_RT8973A is not set
@@ -8598,6 +8614,9 @@ CONFIG_ADXL367_I2C=m
CONFIG_ADXL372=m
CONFIG_ADXL372_SPI=m
CONFIG_ADXL372_I2C=m
+CONFIG_ADXL380=m
+CONFIG_ADXL380_SPI=m
+CONFIG_ADXL380_I2C=m
CONFIG_BMA180=m
CONFIG_BMA220=m
CONFIG_BMA400=m
@@ -8650,7 +8669,9 @@ CONFIG_STK8BA50=m
#
# Analog to digital converters
#
+# CONFIG_AD4000 is not set
# CONFIG_AD4130 is not set
+# CONFIG_AD4695 is not set
# CONFIG_AD7091R5 is not set
# CONFIG_AD7091R8 is not set
# CONFIG_AD7124 is not set
@@ -8701,6 +8722,7 @@ CONFIG_AD7280=m
# CONFIG_MCP3564 is not set
# CONFIG_MCP3911 is not set
# CONFIG_NAU7802 is not set
+# CONFIG_PAC1921 is not set
# CONFIG_PAC1934 is not set
# CONFIG_RICHTEK_RTQ6056 is not set
# CONFIG_SD_ADC_MODULATOR is not set
@@ -8835,6 +8857,7 @@ CONFIG_IIO_ST_SENSORS_CORE=m
# CONFIG_DS4424 is not set
# CONFIG_LTC1660 is not set
# CONFIG_LTC2632 is not set
+# CONFIG_LTC2664 is not set
# CONFIG_M62332 is not set
# CONFIG_MAX517 is not set
# CONFIG_MAX5522 is not set
@@ -8928,6 +8951,7 @@ CONFIG_ITG3200=m
#
# CONFIG_AM2315 is not set
# CONFIG_DHT11 is not set
+# CONFIG_ENS210 is not set
# CONFIG_HDC100X is not set
# CONFIG_HDC2010 is not set
# CONFIG_HDC3020 is not set
@@ -8977,6 +9001,7 @@ CONFIG_APDS9300=m
CONFIG_APDS9306=m
CONFIG_APDS9960=m
CONFIG_AS73211=m
+CONFIG_BH1745=m
CONFIG_BH1750=m
CONFIG_BH1780=m
CONFIG_CM32181=m
@@ -9119,6 +9144,7 @@ CONFIG_IIO_CROS_EC_BARO=m
# CONFIG_MPRLS0025PA is not set
# CONFIG_MS5611 is not set
# CONFIG_MS5637 is not set
+# CONFIG_SDP500 is not set
# CONFIG_IIO_ST_PRESS is not set
# CONFIG_T5403 is not set
# CONFIG_HP206C is not set
@@ -9135,6 +9161,7 @@ CONFIG_IIO_CROS_EC_BARO=m
# Proximity and distance sensors
#
CONFIG_CROS_EC_MKBP_PROXIMITY=m
+# CONFIG_HX9023S is not set
CONFIG_IRSD200=m
# CONFIG_ISL29501 is not set
# CONFIG_LIDAR_LITE_V2 is not set
@@ -9149,6 +9176,7 @@ CONFIG_IRSD200=m
# CONFIG_SRF08 is not set
# CONFIG_VCNL3020 is not set
# CONFIG_VL53L0X_I2C is not set
+# CONFIG_AW96103 is not set
# end of Proximity and distance sensors
#
@@ -9374,6 +9402,7 @@ CONFIG_BCACHEFS_POSIX_ACL=y
CONFIG_BCACHEFS_LOCK_TIME_STATS=y
# CONFIG_BCACHEFS_NO_LATENCY_ACCT is not set
CONFIG_BCACHEFS_SIX_OPTIMISTIC_SPIN=y
+# CONFIG_BCACHEFS_PATH_TRACEPOINTS is not set
# CONFIG_ZONEFS_FS is not set
# CONFIG_FS_DAX is not set
CONFIG_FS_POSIX_ACL=y
@@ -9471,6 +9500,7 @@ CONFIG_HUGETLBFS=y
# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set
CONFIG_HUGETLB_PAGE=y
CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING=y
CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
CONFIG_CONFIGFS_FS=m
CONFIG_EFIVAR_FS=y
@@ -9563,6 +9593,7 @@ CONFIG_EROFS_FS=m
CONFIG_EROFS_FS_XATTR=y
CONFIG_EROFS_FS_POSIX_ACL=y
CONFIG_EROFS_FS_SECURITY=y
+CONFIG_EROFS_FS_BACKED_BY_FILE=y
CONFIG_EROFS_FS_ZIP=y
CONFIG_EROFS_FS_ZIP_LZMA=y
CONFIG_EROFS_FS_ZIP_DEFLATE=y
@@ -9607,6 +9638,7 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_ACL_SUPPORT=m
CONFIG_NFS_COMMON=y
+# CONFIG_NFS_LOCALIO is not set
CONFIG_NFS_V4_2_SSC_HELPER=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
@@ -9632,6 +9664,7 @@ CONFIG_CIFS_DEBUG=y
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_SWN_UPCALL=y
# CONFIG_CIFS_FSCACHE is not set
+CONFIG_CIFS_COMPRESSION=y
# CONFIG_SMB_SERVER is not set
CONFIG_SMBFS=m
CONFIG_CODA_FS=m
@@ -9744,6 +9777,7 @@ CONFIG_SECURITY_YAMA=y
# CONFIG_SECURITY_SAFESETID is not set
# CONFIG_SECURITY_LOCKDOWN_LSM is not set
# CONFIG_SECURITY_LANDLOCK is not set
+# CONFIG_SECURITY_IPE is not set
CONFIG_INTEGRITY=y
# CONFIG_INTEGRITY_SIGNATURE is not set
CONFIG_INTEGRITY_AUDIT=y
@@ -10141,7 +10175,9 @@ CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_ARM64=y
CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_RISCV=y
CONFIG_XZ_DEC_MICROLZMA=y
CONFIG_XZ_DEC_BCJ=y
# CONFIG_XZ_DEC_TEST is not set
@@ -10168,7 +10204,7 @@ CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
-CONFIG_DMA_OPS=y
+CONFIG_DMA_OPS_HELPERS=y
CONFIG_NEED_SG_DMA_FLAGS=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
@@ -10391,7 +10427,6 @@ CONFIG_SCHED_INFO=y
CONFIG_SCHEDSTATS=y
# end of Scheduler Debugging
-# CONFIG_DEBUG_TIMEKEEPING is not set
CONFIG_DEBUG_PREEMPT=y
#
@@ -10581,6 +10616,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_LKDTM is not set
# CONFIG_TEST_MIN_HEAP is not set
# CONFIG_TEST_DIV64 is not set
+# CONFIG_TEST_MULDIV64 is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_TEST_REF_TRACKER is not set
# CONFIG_RBTREE_TEST is not set
diff --git a/packages/l/linux-current/files/patches/build/0001-Make-compiler-calls-ccache-friendly.patch b/packages/l/linux-current/files/patches/build/0001-Make-compiler-calls-ccache-friendly.patch
index 51464c0f9b9..8c8a6f393cf 100644
--- a/packages/l/linux-current/files/patches/build/0001-Make-compiler-calls-ccache-friendly.patch
+++ b/packages/l/linux-current/files/patches/build/0001-Make-compiler-calls-ccache-friendly.patch
@@ -1,4 +1,4 @@
-From 805d4ae78d74a2ee7a6fc4343aa08d82eccb26a9 Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bastian Blank
Date: Mon, 7 Nov 2022 19:33:25 +0000
Subject: [PATCH] Make compiler calls ccache friendly
@@ -13,12 +13,12 @@ This is only tested on gcc, so not forwarded.
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
-index 68d0134bdbf9..c3f0b2372d87 100644
+index 01a9f567d5af..f62f47ac5f1a 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
-@@ -227,17 +227,17 @@ modkern_aflags = $(if $(part-of-module), \
+@@ -222,17 +222,17 @@ modkern_aflags = $(if $(part-of-module), \
$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \
- $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
+ $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) $(modfile_flags))
-c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+c_flags = -MMD -MF $(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
@@ -30,13 +30,10 @@ index 68d0134bdbf9..c3f0b2372d87 100644
-a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+a_flags = -MMD -MF $(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
- $(_a_flags) $(modkern_aflags)
+ $(_a_flags) $(modkern_aflags) $(modname_flags)
-cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+cpp_flags = -MMD -MF $(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(_cpp_flags)
ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
---
-2.42.0
-
diff --git a/packages/l/linux-current/files/patches/build/0001-solus-Don-t-automatically-compress-modules.patch b/packages/l/linux-current/files/patches/build/0001-solus-Don-t-automatically-compress-modules.patch
deleted file mode 100644
index b7a15e8623b..00000000000
--- a/packages/l/linux-current/files/patches/build/0001-solus-Don-t-automatically-compress-modules.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Reilly Brogan
-Date: Wed, 25 Oct 2023 12:02:27 -0500
-Subject: [PATCH] solus: Don't automatically compress modules
-
-If CONFIG_MODULE_COMPRESS_ZSTD is set then the kernel will automatically compress modules when `make modules_install` is called. This is not ideal as we would prefer to handle uncompressed modules and would need to add an additional decompression step only to re-compress them later.
-
-However, if CONFIG_MODULE_COMPRESS_ZSTD is not set then the kernel is not compiled with built-in module decompression support. This is less efficient for our purposes too since we'd rather the kernel do module decompression rather than delegating it to user-space.
-
-So instead let's just force the `modules_install` target to skip compression entirely. This keeps kernel decompression support and allows us to work with uncompressed kernel modules
----
- scripts/Makefile.modinst | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
-index 0afd75472679f..10592f74e3edc 100644
---- a/scripts/Makefile.modinst
-+++ b/scripts/Makefile.modinst
-@@ -53,7 +53,7 @@ $(foreach x, % :, $(if $(findstring $x, $(dst)), \
- suffix-y :=
- suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz
- suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
--suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst
-+suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) :=
-
- modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules))
- install-$(CONFIG_MODULES) += $(modules)
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0001-Fix-ROG-ALLY-X-audio.patch b/packages/l/linux-current/files/patches/hardware/asus/0001-Fix-ROG-ALLY-X-audio.patch
deleted file mode 100644
index 3f99c934530..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0001-Fix-ROG-ALLY-X-audio.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jonathan LoBue
-Date: Sat, 13 Jul 2024 00:12:06 -0700
-Subject: [PATCH 01/18] Fix ROG ALLY X audio
-
-Patch to test fixing TAS2781 amp getting bound properly to i2c
-for ASUS ROG ALLY X.
----
- sound/pci/hda/patch_realtek.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
-index a2737c1ff920..c95a056ed764 100644
---- a/sound/pci/hda/patch_realtek.c
-+++ b/sound/pci/hda/patch_realtek.c
-@@ -7646,6 +7646,7 @@ enum {
- ALC285_FIXUP_THINKPAD_X1_GEN7,
- ALC285_FIXUP_THINKPAD_HEADSET_JACK,
- ALC294_FIXUP_ASUS_ALLY,
-+ ALC294_FIXUP_ASUS_ALLY_X,
- ALC294_FIXUP_ASUS_ALLY_PINS,
- ALC294_FIXUP_ASUS_ALLY_VERBS,
- ALC294_FIXUP_ASUS_ALLY_SPEAKER,
-@@ -9117,6 +9118,12 @@ static const struct hda_fixup alc269_fixups[] = {
- .chained = true,
- .chain_id = ALC294_FIXUP_ASUS_ALLY_PINS
- },
-+ [ALC294_FIXUP_ASUS_ALLY_X] = {
-+ .type = HDA_FIXUP_FUNC,
-+ .v.func = tas2781_fixup_i2c,
-+ .chained = true,
-+ .chain_id = ALC294_FIXUP_ASUS_ALLY_PINS
-+ },
- [ALC294_FIXUP_ASUS_ALLY_PINS] = {
- .type = HDA_FIXUP_PINS,
- .v.pins = (const struct hda_pintbl[]) {
-@@ -10590,6 +10597,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
- SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
- SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally NR2301L/X", ALC294_FIXUP_ASUS_ALLY),
-+ SND_PCI_QUIRK(0x1043, 0x1eb3, "ROG Ally X RC72LA", ALC294_FIXUP_ASUS_ALLY_X),
- SND_PCI_QUIRK(0x1043, 0x1863, "ASUS UX6404VI/VV", ALC245_FIXUP_CS35L41_SPI_2),
- SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
- SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0004-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch b/packages/l/linux-current/files/patches/hardware/asus/0001-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch
similarity index 87%
rename from packages/l/linux-current/files/patches/hardware/asus/0004-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch
rename to packages/l/linux-current/files/patches/hardware/asus/0001-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch
index 3f53fbb0170..c2953997793 100644
--- a/packages/l/linux-current/files/patches/hardware/asus/0004-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch
+++ b/packages/l/linux-current/files/patches/hardware/asus/0001-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones"
Date: Fri, 7 Jun 2024 15:58:01 +1200
-Subject: [PATCH 04/18] Input: xpad - add support for ASUS ROG RAIKIRI PRO
+Subject: [PATCH 01/27] Input: xpad - add support for ASUS ROG RAIKIRI PRO
Add the VID/PID for ASUS ROG RAIKIRI PRO to
xpad_device and the VID to xpad_table.
@@ -12,10 +12,10 @@ Signed-off-by: Luke D. Jones
1 file changed, 1 insertion(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
-index 06104a4e0fdc..fa81225b9fe4 100644
+index 0f23be98c56e..1b92729bd378 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
-@@ -209,6 +209,7 @@
+@@ -210,6 +210,7 @@
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0002-platform-x86-asus-wmi-add-support-for-vivobook-fan-p.patch b/packages/l/linux-current/files/patches/hardware/asus/0002-platform-x86-asus-wmi-add-support-for-vivobook-fan-p.patch
deleted file mode 100644
index 62b683ae713..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0002-platform-x86-asus-wmi-add-support-for-vivobook-fan-p.patch
+++ /dev/null
@@ -1,297 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mohamed Ghanmi
-Date: Sun, 9 Jun 2024 15:48:49 +0100
-Subject: [PATCH 02/18] platform/x86: asus-wmi: add support for vivobook fan
- profiles
-
-Add support for vivobook fan profiles wmi call on the ASUS VIVOBOOK
-to adjust power limits.
-
-These fan profiles have a different device id than the ROG series
-and different order. This reorders the existing modes.
-
-As part of keeping the patch clean the throttle_thermal_policy_available
-boolean stored in the driver struct is removed and
-throttle_thermal_policy_dev is used in place (as on init it is zeroed).
-
-Co-developed-by: Luke D. Jones
-Signed-off-by: Luke D. Jones
-Signed-off-by: Mohamed Ghanmi
-Reviewed-by: Luke D. Jones
-Link: https://lore.kernel.org/r/20240609144849.2532-2-mohamed.ghanmi@supcom.tn
-Reviewed-by: Hans de Goede
-Signed-off-by: Hans de Goede
----
- drivers/platform/x86/asus-wmi.c | 120 ++++++++++++---------
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 71 insertions(+), 50 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 321a658e4554..ace9b887f833 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -97,6 +97,12 @@ module_param(fnlock_default, bool, 0444);
- #define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1
- #define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2
-
-+#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO 0
-+#define ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO 1
-+#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO 2
-+
-+#define PLATFORM_PROFILE_MAX 2
-+
- #define USB_INTEL_XUSB2PR 0xD0
- #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
-
-@@ -300,8 +306,8 @@ struct asus_wmi {
- u32 kbd_rgb_dev;
- bool kbd_rgb_state_available;
-
-- bool throttle_thermal_policy_available;
- u8 throttle_thermal_policy_mode;
-+ u32 throttle_thermal_policy_dev;
-
- bool cpu_fan_curve_available;
- bool gpu_fan_curve_available;
-@@ -3186,7 +3192,7 @@ static int fan_curve_get_factory_default(struct asus_wmi *asus, u32 fan_dev)
- int err, fan_idx;
- u8 mode = 0;
-
-- if (asus->throttle_thermal_policy_available)
-+ if (asus->throttle_thermal_policy_dev)
- mode = asus->throttle_thermal_policy_mode;
- /* DEVID_PU_FAN_CURVE is switched for OVERBOOST vs SILENT */
- if (mode == 2)
-@@ -3393,7 +3399,7 @@ static ssize_t fan_curve_enable_store(struct device *dev,
- * For machines with throttle this is the only way to reset fans
- * to default mode of operation (does not erase curve data).
- */
-- if (asus->throttle_thermal_policy_available) {
-+ if (asus->throttle_thermal_policy_dev) {
- err = throttle_thermal_policy_write(asus);
- if (err)
- return err;
-@@ -3610,8 +3616,8 @@ static const struct attribute_group asus_fan_curve_attr_group = {
- __ATTRIBUTE_GROUPS(asus_fan_curve_attr);
-
- /*
-- * Must be initialised after throttle_thermal_policy_check_present() as
-- * we check the status of throttle_thermal_policy_available during init.
-+ * Must be initialised after throttle_thermal_policy_dev is set as
-+ * we check the status of throttle_thermal_policy_dev during init.
- */
- static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
- {
-@@ -3652,38 +3658,13 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
- }
-
- /* Throttle thermal policy ****************************************************/
--
--static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
--{
-- u32 result;
-- int err;
--
-- asus->throttle_thermal_policy_available = false;
--
-- err = asus_wmi_get_devstate(asus,
-- ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
-- &result);
-- if (err) {
-- if (err == -ENODEV)
-- return 0;
-- return err;
-- }
--
-- if (result & ASUS_WMI_DSTS_PRESENCE_BIT)
-- asus->throttle_thermal_policy_available = true;
--
-- return 0;
--}
--
- static int throttle_thermal_policy_write(struct asus_wmi *asus)
- {
-- int err;
-- u8 value;
-+ u8 value = asus->throttle_thermal_policy_mode;
- u32 retval;
-+ int err;
-
-- value = asus->throttle_thermal_policy_mode;
--
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
-+ err = asus_wmi_set_devstate(asus->throttle_thermal_policy_dev,
- value, &retval);
-
- sysfs_notify(&asus->platform_device->dev.kobj, NULL,
-@@ -3713,7 +3694,7 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus)
-
- static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
- {
-- if (!asus->throttle_thermal_policy_available)
-+ if (!asus->throttle_thermal_policy_dev)
- return 0;
-
- asus->throttle_thermal_policy_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
-@@ -3725,7 +3706,7 @@ static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
- u8 new_mode = asus->throttle_thermal_policy_mode + 1;
- int err;
-
-- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
-+ if (new_mode > PLATFORM_PROFILE_MAX)
- new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
-
- asus->throttle_thermal_policy_mode = new_mode;
-@@ -3764,7 +3745,7 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
- if (result < 0)
- return result;
-
-- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
-+ if (new_mode > PLATFORM_PROFILE_MAX)
- return -EINVAL;
-
- asus->throttle_thermal_policy_mode = new_mode;
-@@ -3781,10 +3762,52 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
- return count;
- }
-
--// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
-+/*
-+ * Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
-+ */
- static DEVICE_ATTR_RW(throttle_thermal_policy);
-
- /* Platform profile ***********************************************************/
-+static int asus_wmi_platform_profile_to_vivo(struct asus_wmi *asus, int mode)
-+{
-+ bool vivo;
-+
-+ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
-+
-+ if (vivo) {
-+ switch (mode) {
-+ case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT:
-+ return ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO;
-+ case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST:
-+ return ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO;
-+ case ASUS_THROTTLE_THERMAL_POLICY_SILENT:
-+ return ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO;
-+ }
-+ }
-+
-+ return mode;
-+}
-+
-+static int asus_wmi_platform_profile_mode_from_vivo(struct asus_wmi *asus, int mode)
-+{
-+ bool vivo;
-+
-+ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
-+
-+ if (vivo) {
-+ switch (mode) {
-+ case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO:
-+ return ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
-+ case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO:
-+ return ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST;
-+ case ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO:
-+ return ASUS_THROTTLE_THERMAL_POLICY_SILENT;
-+ }
-+ }
-+
-+ return mode;
-+}
-+
- static int asus_wmi_platform_profile_get(struct platform_profile_handler *pprof,
- enum platform_profile_option *profile)
- {
-@@ -3792,10 +3815,9 @@ static int asus_wmi_platform_profile_get(struct platform_profile_handler *pprof,
- int tp;
-
- asus = container_of(pprof, struct asus_wmi, platform_profile_handler);
--
- tp = asus->throttle_thermal_policy_mode;
-
-- switch (tp) {
-+ switch (asus_wmi_platform_profile_mode_from_vivo(asus, tp)) {
- case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT:
- *profile = PLATFORM_PROFILE_BALANCED;
- break;
-@@ -3834,7 +3856,7 @@ static int asus_wmi_platform_profile_set(struct platform_profile_handler *pprof,
- return -EOPNOTSUPP;
- }
-
-- asus->throttle_thermal_policy_mode = tp;
-+ asus->throttle_thermal_policy_mode = asus_wmi_platform_profile_to_vivo(asus, tp);
- return throttle_thermal_policy_write(asus);
- }
-
-@@ -3847,7 +3869,7 @@ static int platform_profile_setup(struct asus_wmi *asus)
- * Not an error if a component platform_profile relies on is unavailable
- * so early return, skipping the setup of platform_profile.
- */
-- if (!asus->throttle_thermal_policy_available)
-+ if (!asus->throttle_thermal_policy_dev)
- return 0;
-
- dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n");
-@@ -4262,7 +4284,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
- if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) {
- if (asus->fan_boost_mode_available)
- fan_boost_mode_switch_next(asus);
-- if (asus->throttle_thermal_policy_available)
-+ if (asus->throttle_thermal_policy_dev)
- throttle_thermal_policy_switch_next(asus);
- return;
-
-@@ -4434,7 +4456,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_fan_boost_mode.attr)
- ok = asus->fan_boost_mode_available;
- else if (attr == &dev_attr_throttle_thermal_policy.attr)
-- ok = asus->throttle_thermal_policy_available;
-+ ok = asus->throttle_thermal_policy_dev != 0;
- else if (attr == &dev_attr_ppt_pl2_sppt.attr)
- devid = ASUS_WMI_DEVID_PPT_PL2_SPPT;
- else if (attr == &dev_attr_ppt_pl1_spl.attr)
-@@ -4726,16 +4748,15 @@ static int asus_wmi_add(struct platform_device *pdev)
- else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2))
- asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2;
-
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
-+ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY;
-+ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO))
-+ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
-+
- err = fan_boost_mode_check_present(asus);
- if (err)
- goto fail_fan_boost_mode;
-
-- err = throttle_thermal_policy_check_present(asus);
-- if (err)
-- goto fail_throttle_thermal_policy;
-- else
-- throttle_thermal_policy_set_default(asus);
--
- err = platform_profile_setup(asus);
- if (err)
- goto fail_platform_profile_setup;
-@@ -4830,7 +4851,6 @@ static int asus_wmi_add(struct platform_device *pdev)
- fail_input:
- asus_wmi_sysfs_exit(asus->platform_device);
- fail_sysfs:
--fail_throttle_thermal_policy:
- fail_custom_fan_curve:
- fail_platform_profile_setup:
- if (asus->platform_profile_support)
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index ae9bf7479e7b..c854f4bc6062 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -69,6 +69,7 @@
- #define ASUS_WMI_DEVID_SCREENPAD_LIGHT 0x00050032
- #define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018
- #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075
-+#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019
-
- /* Misc */
- #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0006-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch b/packages/l/linux-current/files/patches/hardware/asus/0002-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch
similarity index 58%
rename from packages/l/linux-current/files/patches/hardware/asus/0006-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch
rename to packages/l/linux-current/files/patches/hardware/asus/0002-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch
index ed08f0f47dc..06ea42dd79b 100644
--- a/packages/l/linux-current/files/patches/hardware/asus/0006-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch
+++ b/packages/l/linux-current/files/patches/hardware/asus/0002-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones"
Date: Fri, 24 May 2024 10:54:36 +1200
-Subject: [PATCH 06/18] platform/x86: asus-wmi: don't fail if platform_profile
+Subject: [PATCH 02/27] platform/x86: asus-wmi: don't fail if platform_profile
already registered
On some newer laptops it appears that an AMD driver can register a
@@ -15,29 +15,14 @@ We can safely continue loading the driver instead of bombing out.
Signed-off-by: Luke D. Jones
---
- drivers/platform/x86/asus-wmi.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
+ drivers/platform/x86/asus-wmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 2d62cf1ed647..08861792bddd 100644
+index 1101e5b2488e..293ecd228a5a 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
-@@ -3921,8 +3921,13 @@ static int platform_profile_setup(struct asus_wmi *asus)
- asus->platform_profile_handler.choices);
-
- err = platform_profile_register(&asus->platform_profile_handler);
-- if (err)
-+ if (err == -EEXIST) {
-+ pr_warn("%s, a platform_profile handler is already registered\n", __func__);
-+ return 0;
-+ } else if (err) {
-+ pr_err("%s, failed at platform_profile_register: %d\n", __func__, err);
- return err;
-+ }
-
- asus->platform_profile_support = true;
- return 0;
-@@ -4797,7 +4802,7 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -4769,7 +4769,7 @@ static int asus_wmi_add(struct platform_device *pdev)
goto fail_fan_boost_mode;
err = platform_profile_setup(asus);
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0003-hid-asus-use-hid-for-brightness-control-on-keyboard.patch b/packages/l/linux-current/files/patches/hardware/asus/0003-hid-asus-use-hid-for-brightness-control-on-keyboard.patch
deleted file mode 100644
index 19f4f8ba5ee..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0003-hid-asus-use-hid-for-brightness-control-on-keyboard.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones"
-Date: Sat, 13 Jul 2024 19:47:33 +1200
-Subject: [PATCH 03/18] hid-asus: use hid for brightness control on keyboard
-
-On almost all ASUS ROG series laptops the MCU used for the USB keyboard
-also has a HID packet used for setting the brightness. This is usually
-the same as the WMI method. But in some laptops the WMI method either
-is missing or doesn't work, so we should default to the HID control.
-
-Signed-off-by: Luke D. Jones
-Acked-by: Benjamin Tissoires
-Link: https://lore.kernel.org/r/20240713074733.77334-2-luke@ljones.dev
-Reviewed-by: Hans de Goede
-Signed-off-by: Hans de Goede
----
- drivers/hid/hid-asus.c | 7 +++++
- drivers/platform/x86/asus-wmi.c | 3 +-
- include/linux/platform_data/x86/asus-wmi.h | 36 ++++++++++++++++++++++
- 3 files changed, 45 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
-index a282388b7aa5..659cf9c96e26 100644
---- a/drivers/hid/hid-asus.c
-+++ b/drivers/hid/hid-asus.c
-@@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work)
- */
- static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
- {
-+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
- u32 value;
- int ret;
-
- if (!IS_ENABLED(CONFIG_ASUS_WMI))
- return false;
-
-+ if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
-+ dmi_check_system(asus_use_hid_led_dmi_ids)) {
-+ hid_info(hdev, "using HID for asus::kbd_backlight\n");
-+ return false;
-+ }
-+
- ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
- ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
- hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index ace9b887f833..83a710cf7ec1 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -1728,7 +1728,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
- goto error;
- }
-
-- if (!kbd_led_read(asus, &led_val, NULL)) {
-+ if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
-+ pr_info("using asus-wmi for asus::kbd_backlight\n");
- asus->kbd_led_wk = led_val;
- asus->kbd_led.name = "asus::kbd_backlight";
- asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index c854f4bc6062..365e119bebaa 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -4,6 +4,7 @@
-
- #include
- #include
-+#include
-
- /* WMI Methods */
- #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
-@@ -166,4 +167,39 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
- }
- #endif
-
-+/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */
-+static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = {
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "GA403U"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "GU605M"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
-+ },
-+ },
-+ { },
-+};
-+
- #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0010-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch b/packages/l/linux-current/files/patches/hardware/asus/0003-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch
similarity index 72%
rename from packages/l/linux-current/files/patches/hardware/asus/0010-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch
rename to packages/l/linux-current/files/patches/hardware/asus/0003-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch
index 5ac45747a80..0e51d4ed1af 100644
--- a/packages/l/linux-current/files/patches/hardware/asus/0010-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch
+++ b/packages/l/linux-current/files/patches/hardware/asus/0003-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones"
Date: Sun, 1 Sep 2024 14:30:37 +1200
-Subject: [PATCH 10/18] platform/x86: asus-wmi: Refactor Ally suspend/resume
+Subject: [PATCH 03/27] platform/x86: asus-wmi: Refactor Ally suspend/resume
The CSEE method from ACPI is now called only on module load. This fixes
an issues with USB device loss on Ally 1 after reboot.
@@ -10,20 +10,23 @@ Both Ally 1 and Ally X now rely only of the _DSM screen off/on calls
exposed in AMD s2idle to call the CSEE (which is done in the _DSM), plus
a small additional delay to allow the MCU time to do USB unplug/plug.
-The mcu_powersave feature is now forced off by default and the attributes
-hidden. This is a temporary measure while the issues with it are being
-solved with help from ASUS.
+Note: a new MCU FW is being released on 2024/10/16 which will completely
+fix the issue this quirk series has been trying to fix, and it will be
+able to be removed in full some time in the future. This quirk series
+has also been tested with a test version of this FW fix with no ill
+effects - users will notice only that powersave becomes reliable 100% of
+the time.
Signed-off-by: Luke D. Jones
---
- drivers/platform/x86/asus-wmi.c | 97 ++++++++++++++++++++-------------
- 1 file changed, 59 insertions(+), 38 deletions(-)
+ drivers/platform/x86/asus-wmi.c | 86 ++++++++++++++++++---------------
+ 1 file changed, 48 insertions(+), 38 deletions(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 08861792bddd..26684d78625e 100644
+index 293ecd228a5a..acd0ec1d9aae 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
-@@ -143,16 +143,19 @@ module_param(fnlock_default, bool, 0444);
+@@ -142,16 +142,20 @@ module_param(fnlock_default, bool, 0444);
#define ASUS_MINI_LED_2024_STRONG 0x01
#define ASUS_MINI_LED_2024_OFF 0x02
@@ -36,6 +39,7 @@ index 08861792bddd..26684d78625e 100644
+ * Time here greatly impacts the wake behaviour. Used in suspend/wake.
+ */
+#define ASUS_USB0_PWR_EC0_CSEE_WAIT 600
++#define ASUS_USB0_PWR_EC0_CSEE_OFF 0xB7
+#define ASUS_USB0_PWR_EC0_CSEE_ON 0xB8
static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
@@ -47,7 +51,7 @@ index 08861792bddd..26684d78625e 100644
{
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
-@@ -275,9 +278,6 @@ struct asus_wmi {
+@@ -274,9 +278,6 @@ struct asus_wmi {
u32 tablet_switch_dev_id;
bool tablet_switch_inverted;
@@ -57,53 +61,34 @@ index 08861792bddd..26684d78625e 100644
enum fan_type fan_type;
enum fan_type gpu_fan_type;
enum fan_type mid_fan_type;
-@@ -336,6 +336,8 @@ struct asus_wmi {
+@@ -335,6 +336,8 @@ struct asus_wmi {
struct asus_wmi_driver *driver;
};
-+static bool ally_mcu_usb_switch;
++static bool ally_mcu_usb_plug;
+
/* WMI ************************************************************************/
static int asus_wmi_evaluate_method3(u32 method_id,
-@@ -4524,6 +4526,13 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_available_mini_led_mode.attr)
- ok = asus->mini_led_dev_id != 0;
-
-+ /*
-+ * Temporary: we don't want to remove the full mcu_powersave code just yet
-+ * as this _will_ be fixed at some point soon with help from ASUS.
-+ */
-+ if (attr == &dev_attr_mcu_powersave.attr)
-+ return 0;
-+
- if (devid != -1) {
- ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
- pr_debug("%s called 0x%08x, ok: %x\n", __func__, devid, ok);
-@@ -4762,6 +4771,22 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -4729,6 +4732,17 @@ static int asus_wmi_add(struct platform_device *pdev)
if (err)
goto fail_platform;
-+ ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
++ ally_mcu_usb_plug = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
+ && dmi_check_system(asus_rog_ally_device);
-+ if (ally_mcu_usb_switch) {
++ if (ally_mcu_usb_plug) {
+ /*
+ * These steps ensure the device is in a valid good state, this is
+ * especially important for the Ally 1 after a reboot.
+ */
+ acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, ASUS_USB0_PWR_EC0_CSEE_ON);
+ msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
-+ platform_suspend_screen_on();
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, 0, &result);
-+ if (err)
-+ pr_warn("Failed to force MCU powersave off for Ally device: %d\n", err);
+ }
+
/* ensure defaults for tunables */
asus->ppt_pl2_sppt = 5;
asus->ppt_pl1_spl = 5;
-@@ -4774,8 +4799,6 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -4741,8 +4755,6 @@ static int asus_wmi_add(struct platform_device *pdev)
asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
@@ -112,7 +97,7 @@ index 08861792bddd..26684d78625e 100644
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE))
asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;
-@@ -4966,34 +4989,6 @@ static int asus_hotk_resume(struct device *device)
+@@ -4933,34 +4945,6 @@ static int asus_hotk_resume(struct device *device)
return 0;
}
@@ -147,22 +132,22 @@ index 08861792bddd..26684d78625e 100644
static int asus_hotk_restore(struct device *device)
{
struct asus_wmi *asus = dev_get_drvdata(device);
-@@ -5034,11 +5029,32 @@ static int asus_hotk_restore(struct device *device)
+@@ -5001,11 +4985,32 @@ static int asus_hotk_restore(struct device *device)
return 0;
}
+static void asus_ally_s2idle_restore(void)
+{
-+ if (ally_mcu_usb_switch) {
-+ platform_suspend_screen_on();
++ if (ally_mcu_usb_plug) {
++ acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, ASUS_USB0_PWR_EC0_CSEE_ON);
+ msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
+ }
+}
+
+static int asus_hotk_prepare(struct device *device)
+{
-+ if (ally_mcu_usb_switch) {
-+ platform_suspend_screen_off();
++ if (ally_mcu_usb_plug) {
++ acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, ASUS_USB0_PWR_EC0_CSEE_OFF);
+ msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
+ }
+ return 0;
@@ -181,7 +166,7 @@ index 08861792bddd..26684d78625e 100644
.prepare = asus_hotk_prepare,
};
-@@ -5066,6 +5082,10 @@ static int asus_wmi_probe(struct platform_device *pdev)
+@@ -5033,6 +5038,10 @@ static int asus_wmi_probe(struct platform_device *pdev)
return ret;
}
@@ -192,7 +177,7 @@ index 08861792bddd..26684d78625e 100644
return asus_wmi_add(pdev);
}
-@@ -5098,6 +5118,7 @@ EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
+@@ -5065,6 +5074,7 @@ EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
{
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0004-platform-x86-asus-wmi-export-symbols-used-for-read-w.patch b/packages/l/linux-current/files/patches/hardware/asus/0004-platform-x86-asus-wmi-export-symbols-used-for-read-w.patch
new file mode 100644
index 00000000000..c16d690253c
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0004-platform-x86-asus-wmi-export-symbols-used-for-read-w.patch
@@ -0,0 +1,107 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sun, 22 Sep 2024 21:40:46 +1200
+Subject: [PATCH 04/27] platform/x86: asus-wmi: export symbols used for
+ read/write WMI
+
+Export some rather helpful read/write WMI symbols using a namespace.
+These are DEVS and DSTS only, or require the arg0 input.
+
+Also does a slight refactor of internals of these functions.
+
+Signed-off-by: Luke D. Jones
+Reviewed-by: Mario Limonciello
+---
+ drivers/platform/x86/asus-wmi.c | 44 ++++++++++++++++++++--
+ include/linux/platform_data/x86/asus-wmi.h | 10 +++++
+ 2 files changed, 51 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index acd0ec1d9aae..6da2c7715a9f 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -388,7 +388,7 @@ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
+ {
+ return asus_wmi_evaluate_method3(method_id, arg0, arg1, 0, retval);
+ }
+-EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method);
++EXPORT_SYMBOL_NS_GPL(asus_wmi_evaluate_method, ASUS_WMI);
+
+ static int asus_wmi_evaluate_method5(u32 method_id,
+ u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 *retval)
+@@ -552,12 +552,50 @@ static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
+ return 0;
+ }
+
+-static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
+- u32 *retval)
++/**
++ * asus_wmi_get_devstate_dsts() - Get the WMI function state.
++ * @dev_id: The WMI method ID to call.
++ * @retval: A pointer to where to store the value returned from WMI.
++ *
++ * On success the return value is 0, and the retval is a valid value returned
++ * by the successful WMI function call otherwise an error is returned if the
++ * call failed, or if the WMI method ID is unsupported.
++ */
++int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
++{
++ int err;
++
++ err = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0, retval);
++ if (err)
++ return err;
++
++ if (*retval == ASUS_WMI_UNSUPPORTED_METHOD)
++ return -ENODEV;
++
++ return 0;
++}
++EXPORT_SYMBOL_NS_GPL(asus_wmi_get_devstate_dsts, ASUS_WMI);
++
++/**
++ * asus_wmi_set_devstate() - Set the WMI function state.
++ * @dev_id: The WMI function to call.
++ * @ctrl_param: The argument to be used for this WMI function.
++ * @retval: A pointer to where to store the value returned from WMI.
++ *
++ * The returned WMI function state if not checked here for error as
++ * asus_wmi_set_devstate() is not called unless first paired with a call to
++ * asus_wmi_get_devstate_dsts() to check that the WMI function is supported.
++ *
++ * On success the return value is 0, and the retval is a valid value returned
++ * by the successful WMI function call. An error value is returned only if the
++ * WMI function failed.
++ */
++int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval)
+ {
+ return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
+ ctrl_param, retval);
+ }
++EXPORT_SYMBOL_NS_GPL(asus_wmi_set_devstate, ASUS_WMI);
+
+ /* Helper for special devices with magic return codes */
+ static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
+diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
+index 365e119bebaa..6ea4dedfb85e 100644
+--- a/include/linux/platform_data/x86/asus-wmi.h
++++ b/include/linux/platform_data/x86/asus-wmi.h
+@@ -158,8 +158,18 @@
+ #define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F
+
+ #if IS_REACHABLE(CONFIG_ASUS_WMI)
++int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval);
++int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval);
+ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
+ #else
++static inline int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
++{
++ return -ENODEV;
++}
++static inline int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval)
++{
++ return -ENODEV;
++}
+ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
+ u32 *retval)
+ {
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0005-hid-asus-Add-MODULE_IMPORT_NS-ASUS_WMI.patch b/packages/l/linux-current/files/patches/hardware/asus/0005-hid-asus-Add-MODULE_IMPORT_NS-ASUS_WMI.patch
new file mode 100644
index 00000000000..55994e9aafe
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0005-hid-asus-Add-MODULE_IMPORT_NS-ASUS_WMI.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sat, 21 Sep 2024 16:04:58 +1200
+Subject: [PATCH 05/27] hid-asus: Add MODULE_IMPORT_NS(ASUS_WMI)
+
+A small change to asus_wmi_evaluate_method() was introduced during
+asus-armoury driver development to put the exports behind a namespace.
+
+Import that namespace here.
+
+Signed-off-by: Luke D. Jones
+Acked-by: Jiri Kosina
+---
+ drivers/hid/hid-asus.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
+index a4b47319ad8e..9540e3e19cce 100644
+--- a/drivers/hid/hid-asus.c
++++ b/drivers/hid/hid-asus.c
+@@ -1301,4 +1301,5 @@ static struct hid_driver asus_driver = {
+ };
+ module_hid_driver(asus_driver);
+
++MODULE_IMPORT_NS(ASUS_WMI);
+ MODULE_LICENSE("GPL");
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0005-platform-x86-asus-wmi-add-debug-print-in-more-key-pl.patch b/packages/l/linux-current/files/patches/hardware/asus/0005-platform-x86-asus-wmi-add-debug-print-in-more-key-pl.patch
deleted file mode 100644
index caa64d77824..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0005-platform-x86-asus-wmi-add-debug-print-in-more-key-pl.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones"
-Date: Tue, 10 Sep 2024 17:04:17 +1200
-Subject: [PATCH 05/18] platform/x86: asus-wmi: add debug print in more key
- places
-
-Add more verbose debug print in the WMI method calls. This helps a lot
-with debugging various issues working with regular users as the WMI
-methods can be traced now.
-
-Signed-off-by: Luke D. Jones
----
- drivers/platform/x86/asus-wmi.c | 58 +++++++++++++++++++++++++++------
- 1 file changed, 48 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 83a710cf7ec1..2d62cf1ed647 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -355,20 +355,29 @@ static int asus_wmi_evaluate_method3(u32 method_id,
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
-
-- if (ACPI_FAILURE(status))
-+ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x\n",
-+ __func__, method_id, arg0, arg1, arg2);
-+ if (ACPI_FAILURE(status)) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -EIO);
- return -EIO;
-+ }
-
- obj = (union acpi_object *)output.pointer;
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- tmp = (u32) obj->integer.value;
-
-+ pr_debug("Result: 0x%08x\n", tmp);
- if (retval)
- *retval = tmp;
-
- kfree(obj);
-
-- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
-+ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -ENODEV);
- return -ENODEV;
-+ }
-
- return 0;
- }
-@@ -398,20 +407,29 @@ static int asus_wmi_evaluate_method5(u32 method_id,
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
-
-- if (ACPI_FAILURE(status))
-+ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
-+ __func__, method_id, arg0, arg1, arg2, arg3, arg4);
-+ if (ACPI_FAILURE(status)) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -EIO);
- return -EIO;
-+ }
-
- obj = (union acpi_object *)output.pointer;
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- tmp = (u32) obj->integer.value;
-
-+ pr_debug("Result: %x\n", tmp);
- if (retval)
- *retval = tmp;
-
- kfree(obj);
-
-- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
-+ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -ENODEV);
- return -ENODEV;
-+ }
-
- return 0;
- }
-@@ -437,8 +455,13 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
-
-- if (ACPI_FAILURE(status))
-+ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x\n",
-+ __func__, method_id, arg0, arg1);
-+ if (ACPI_FAILURE(status)) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -EIO);
- return -EIO;
-+ }
-
- obj = (union acpi_object *)output.pointer;
-
-@@ -474,8 +497,11 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
-
- kfree(obj);
-
-- if (err)
-+ if (err) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, err);
- return err;
-+ }
-
- return 0;
- }
-@@ -563,6 +589,7 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
- {
- u32 retval;
- int status = asus_wmi_get_devstate(asus, dev_id, &retval);
-+ pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval);
-
- return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
- }
-@@ -3628,18 +3655,27 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
-
- err = fan_curve_check_present(asus, &asus->cpu_fan_curve_available,
- ASUS_WMI_DEVID_CPU_FAN_CURVE);
-- if (err)
-+ if (err) {
-+ pr_debug("%s, checked 0x%08x, failed: %d\n",
-+ __func__, ASUS_WMI_DEVID_CPU_FAN_CURVE, err);
- return err;
-+ }
-
- err = fan_curve_check_present(asus, &asus->gpu_fan_curve_available,
- ASUS_WMI_DEVID_GPU_FAN_CURVE);
-- if (err)
-+ if (err) {
-+ pr_debug("%s, checked 0x%08x, failed: %d\n",
-+ __func__, ASUS_WMI_DEVID_GPU_FAN_CURVE, err);
- return err;
-+ }
-
- err = fan_curve_check_present(asus, &asus->mid_fan_curve_available,
- ASUS_WMI_DEVID_MID_FAN_CURVE);
-- if (err)
-+ if (err) {
-+ pr_debug("%s, checked 0x%08x, failed: %d\n",
-+ __func__, ASUS_WMI_DEVID_MID_FAN_CURVE, err);
- return err;
-+ }
-
- if (!asus->cpu_fan_curve_available
- && !asus->gpu_fan_curve_available
-@@ -4483,8 +4519,10 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_available_mini_led_mode.attr)
- ok = asus->mini_led_dev_id != 0;
-
-- if (devid != -1)
-+ if (devid != -1) {
- ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
-+ pr_debug("%s called 0x%08x, ok: %x\n", __func__, devid, ok);
-+ }
-
- return ok ? attr->mode : 0;
- }
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0006-platform-x86-asus-armoury-move-existing-tunings-to-a.patch b/packages/l/linux-current/files/patches/hardware/asus/0006-platform-x86-asus-armoury-move-existing-tunings-to-a.patch
new file mode 100644
index 00000000000..161ed7992d7
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0006-platform-x86-asus-armoury-move-existing-tunings-to-a.patch
@@ -0,0 +1,849 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sun, 22 Sep 2024 21:39:43 +1200
+Subject: [PATCH 06/27] platform/x86: asus-armoury: move existing tunings to
+ asus-armoury module
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The fw_attributes_class provides a much cleaner interface to all of the
+attributes introduced to asus-wmi. This patch moves all of these extra
+attributes over to fw_attributes_class, and shifts the bulk of these
+definitions to a new kernel module to reduce the clutter of asus-wmi
+with the intention of deprecating the asus-wmi attributes in future.
+
+The work applies only to WMI methods which don't have a clearly defined
+place within the sysfs and as a result ended up lumped together in
+/sys/devices/platform/asus-nb-wmi/ with no standard API.
+
+Where possible the fw attrs now implement defaults, min, max, scalar,
+choices, etc. As en example dgpu_disable becomes:
+
+/sys/class/firmware-attributes/asus-armoury/attributes/dgpu_disable/
+├── current_value
+├── display_name
+├── possible_values
+└── type
+
+as do other attributes.
+
+The ppt_* based attributes are removed in this initial patch as the
+implementation is somewhat broken due to the WMI methods requiring a
+set of limits on the values accepted (which is not provided by WMI).
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/platform/x86/Kconfig | 12 +
+ drivers/platform/x86/Makefile | 1 +
+ drivers/platform/x86/asus-armoury.c | 573 +++++++++++++++++++++
+ drivers/platform/x86/asus-armoury.h | 147 ++++++
+ drivers/platform/x86/asus-wmi.c | 4 -
+ include/linux/platform_data/x86/asus-wmi.h | 3 +
+ 6 files changed, 736 insertions(+), 4 deletions(-)
+ create mode 100644 drivers/platform/x86/asus-armoury.c
+ create mode 100644 drivers/platform/x86/asus-armoury.h
+
+diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
+index 3875abba5a79..80ec8b45022d 100644
+--- a/drivers/platform/x86/Kconfig
++++ b/drivers/platform/x86/Kconfig
+@@ -265,6 +265,18 @@ config ASUS_WIRELESS
+ If you choose to compile this driver as a module the module will be
+ called asus-wireless.
+
++config ASUS_ARMOURY
++ tristate "ASUS Armoury driver"
++ depends on ASUS_WMI
++ select FW_ATTR_CLASS
++ help
++ Say Y here if you have a WMI aware Asus machine and would like to use the
++ firmware_attributes API to control various settings typically exposed in
++ the ASUS Armoury Crate application available on Windows.
++
++ To compile this driver as a module, choose M here: the module will
++ be called asus-armoury.
++
+ config ASUS_WMI
+ tristate "ASUS WMI Driver"
+ depends on ACPI_WMI
+diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
+index e1b142947067..fe3e7e7dede8 100644
+--- a/drivers/platform/x86/Makefile
++++ b/drivers/platform/x86/Makefile
+@@ -32,6 +32,7 @@ obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
+ # ASUS
+ obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
+ obj-$(CONFIG_ASUS_WIRELESS) += asus-wireless.o
++obj-$(CONFIG_ASUS_ARMOURY) += asus-armoury.o
+ obj-$(CONFIG_ASUS_WMI) += asus-wmi.o
+ obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o
+ obj-$(CONFIG_ASUS_TF103C_DOCK) += asus-tf103c-dock.o
+diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
+new file mode 100644
+index 000000000000..0dd0af6c97e4
+--- /dev/null
++++ b/drivers/platform/x86/asus-armoury.c
+@@ -0,0 +1,573 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Asus Armoury (WMI) attributes driver. This driver uses the fw_attributes
++ * class to expose the various WMI functions that many gaming and some
++ * non-gaming ASUS laptops have available.
++ * These typically don't fit anywhere else in the sysfs such as under LED class,
++ * hwmon or other, and are set in Windows using the ASUS Armoury Crate tool.
++ *
++ * Copyright(C) 2024 Luke Jones
++ */
++
++#include "linux/cleanup.h"
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++
++#include "asus-armoury.h"
++#include "firmware_attributes_class.h"
++
++#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C"
++
++#define ASUS_MINI_LED_MODE_MASK 0x03
++/* Standard modes for devices with only on/off */
++#define ASUS_MINI_LED_OFF 0x00
++#define ASUS_MINI_LED_ON 0x01
++/* Like "on" but the effect is more vibrant or brighter */
++#define ASUS_MINI_LED_STRONG_MODE 0x02
++/* New modes for devices with 3 mini-led mode types */
++#define ASUS_MINI_LED_2024_WEAK 0x00
++#define ASUS_MINI_LED_2024_STRONG 0x01
++#define ASUS_MINI_LED_2024_OFF 0x02
++
++/* Default limits for tunables available on ASUS ROG laptops */
++#define NVIDIA_BOOST_MIN 5
++#define NVIDIA_BOOST_MAX 25
++#define NVIDIA_TEMP_MIN 75
++#define NVIDIA_TEMP_MAX 87
++#define PPT_CPU_LIMIT_MIN 5
++#define PPT_CPU_LIMIT_MAX 150
++#define PPT_CPU_LIMIT_DEFAULT 80
++#define PPT_PLATFORM_MIN 5
++#define PPT_PLATFORM_MAX 100
++#define PPT_PLATFORM_DEFAULT 80
++
++static const struct class *fw_attr_class;
++
++struct asus_armoury_priv {
++ struct device *fw_attr_dev;
++ struct kset *fw_attr_kset;
++
++ u32 mini_led_dev_id;
++ u32 gpu_mux_dev_id;
++
++ struct mutex mutex;
++};
++
++static struct asus_armoury_priv asus_armoury = {
++ .mutex = __MUTEX_INITIALIZER(asus_armoury.mutex)
++};
++
++struct fw_attrs_group {
++ bool pending_reboot;
++};
++
++static struct fw_attrs_group fw_attrs = {
++ .pending_reboot = false,
++};
++
++struct asus_attr_group {
++ const struct attribute_group *attr_group;
++ u32 wmi_devid;
++};
++
++static bool asus_wmi_is_present(u32 dev_id)
++{
++ u32 retval;
++ int status;
++
++ status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0, &retval);
++ pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval);
++
++ return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
++}
++
++static void asus_set_reboot_and_signal_event(void)
++{
++ fw_attrs.pending_reboot = true;
++ kobject_uevent(&asus_armoury.fw_attr_dev->kobj, KOBJ_CHANGE);
++}
++
++static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
++{
++ return sysfs_emit(buf, "%d\n", fw_attrs.pending_reboot);
++}
++
++static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
++
++static bool asus_bios_requires_reboot(struct kobj_attribute *attr)
++{
++ return !strcmp(attr->attr.name, "gpu_mux_mode");
++}
++
++static int armoury_wmi_set_devstate(struct kobj_attribute *attr, u32 value, u32 wmi_dev)
++{
++ u32 result;
++ int err;
++
++ guard(mutex)(&asus_armoury.mutex);
++ err = asus_wmi_set_devstate(wmi_dev, value, &result);
++ if (err) {
++ pr_err("Failed to set %s: %d\n", attr->attr.name, err);
++ return err;
++ }
++ /*
++ * !1 is usually considered a fail by ASUS, but some WMI methods do use > 1
++ * to return a status code or similar.
++ */
++ if (result < 1) {
++ pr_err("Failed to set %s: (result): 0x%x\n", attr->attr.name, result);
++ return -EIO;
++ }
++
++ return 0;
++}
++
++/**
++ * attr_int_store() - Send an int to wmi method, checks if within min/max exclusive.
++ * @kobj: Pointer to the driver object.
++ * @attr: Pointer to the attribute calling this function.
++ * @buf: The buffer to read from, this is parsed to `int` type.
++ * @count: Required by sysfs attribute macros, pass in from the callee attr.
++ * @min: Minimum accepted value. Below this returns -EINVAL.
++ * @max: Maximum accepted value. Above this returns -EINVAL.
++ * @store_value: Pointer to where the parsed value should be stored.
++ * @wmi_dev: The WMI function ID to use.
++ *
++ * This function is intended to be generic so it can be called from any "_store"
++ * attribute which works only with integers. The integer to be sent to the WMI method
++ * is range checked and an error returned if out of range.
++ *
++ * If the value is valid and WMI is success, then the sysfs attribute is notified
++ * and if asus_bios_requires_reboot() is true then reboot attribute is also notified.
++ *
++ * Returns: Either count, or an error.
++ */
++static ssize_t attr_uint_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf,
++ size_t count, u32 min, u32 max, u32 *store_value, u32 wmi_dev)
++{
++ u32 value;
++ int err;
++
++ err = kstrtouint(buf, 10, &value);
++ if (err)
++ return err;
++
++ if (value < min || value > max)
++ return -EINVAL;
++
++ err = armoury_wmi_set_devstate(attr, value, wmi_dev);
++ if (err)
++ return err;
++
++ if (store_value != NULL)
++ *store_value = value;
++ sysfs_notify(kobj, NULL, attr->attr.name);
++
++ if (asus_bios_requires_reboot(attr))
++ asus_set_reboot_and_signal_event();
++
++ return count;
++}
++
++/* Mini-LED mode **************************************************************/
++static ssize_t mini_led_mode_current_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ u32 value;
++ int err;
++
++ err = asus_wmi_get_devstate_dsts(asus_armoury.mini_led_dev_id, &value);
++ if (err)
++ return err;
++
++ value &= ASUS_MINI_LED_MODE_MASK;
++
++ /*
++ * Remap the mode values to match previous generation mini-LED. The last gen
++ * WMI 0 == off, while on this version WMI 2 == off (flipped).
++ */
++ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
++ switch (value) {
++ case ASUS_MINI_LED_2024_WEAK:
++ value = ASUS_MINI_LED_ON;
++ break;
++ case ASUS_MINI_LED_2024_STRONG:
++ value = ASUS_MINI_LED_STRONG_MODE;
++ break;
++ case ASUS_MINI_LED_2024_OFF:
++ value = ASUS_MINI_LED_OFF;
++ break;
++ }
++ }
++
++ return sysfs_emit(buf, "%u\n", value);
++}
++
++static ssize_t mini_led_mode_current_value_store(struct kobject *kobj,
++ struct kobj_attribute *attr,
++ const char *buf, size_t count)
++{
++ u32 mode;
++ int err;
++
++ err = kstrtou32(buf, 10, &mode);
++ if (err)
++ return err;
++
++ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE &&
++ mode > ASUS_MINI_LED_ON)
++ return -EINVAL;
++ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 &&
++ mode > ASUS_MINI_LED_STRONG_MODE)
++ return -EINVAL;
++
++ /*
++ * Remap the mode values so expected behaviour is the same as the last
++ * generation of mini-LED with 0 == off, 1 == on.
++ */
++ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
++ switch (mode) {
++ case ASUS_MINI_LED_OFF:
++ mode = ASUS_MINI_LED_2024_OFF;
++ break;
++ case ASUS_MINI_LED_ON:
++ mode = ASUS_MINI_LED_2024_WEAK;
++ break;
++ case ASUS_MINI_LED_STRONG_MODE:
++ mode = ASUS_MINI_LED_2024_STRONG;
++ break;
++ }
++ }
++
++ err = armoury_wmi_set_devstate(attr, mode, asus_armoury.mini_led_dev_id);
++ if (err)
++ return err;
++
++ sysfs_notify(kobj, NULL, attr->attr.name);
++
++ return count;
++}
++
++static ssize_t mini_led_mode_possible_values_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ switch (asus_armoury.mini_led_dev_id) {
++ case ASUS_WMI_DEVID_MINI_LED_MODE:
++ return sysfs_emit(buf, "0;1\n");
++ case ASUS_WMI_DEVID_MINI_LED_MODE2:
++ return sysfs_emit(buf, "0;1;2\n");
++ }
++
++ return sysfs_emit(buf, "0\n");
++}
++
++ATTR_GROUP_ENUM_CUSTOM(mini_led_mode, "mini_led_mode", "Set the mini-LED backlight mode");
++
++static ssize_t gpu_mux_mode_current_value_store(struct kobject *kobj,
++ struct kobj_attribute *attr, const char *buf,
++ size_t count)
++{
++ int result, err;
++ u32 optimus;
++
++ err = kstrtou32(buf, 10, &optimus);
++ if (err)
++ return err;
++
++ if (optimus > 1)
++ return -EINVAL;
++
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU)) {
++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_DGPU, &result);
++ if (err)
++ return err;
++ if (result && !optimus) {
++ err = -ENODEV;
++ pr_warn("Can not switch MUX to dGPU mode when dGPU is disabled: %02X %02X %d\n",
++ result, optimus, err);
++ return err;
++ }
++ }
++
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_EGPU)) {
++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_EGPU, &result);
++ if (err)
++ return err;
++ if (result && !optimus) {
++ err = -ENODEV;
++ pr_warn("Can not switch MUX to dGPU mode when eGPU is enabled: %d\n",
++ err);
++ return err;
++ }
++ }
++
++ err = armoury_wmi_set_devstate(attr, optimus, asus_armoury.gpu_mux_dev_id);
++ if (err)
++ return err;
++
++ sysfs_notify(kobj, NULL, attr->attr.name);
++ asus_set_reboot_and_signal_event();
++
++ return count;
++}
++WMI_SHOW_INT(gpu_mux_mode_current_value, "%d\n", asus_armoury.gpu_mux_dev_id);
++ATTR_GROUP_BOOL_CUSTOM(gpu_mux_mode, "gpu_mux_mode", "Set the GPU display MUX mode");
++
++/*
++ * A user may be required to store the value twice, typical store first, then
++ * rescan PCI bus to activate power, then store a second time to save correctly.
++ */
++static ssize_t dgpu_disable_current_value_store(struct kobject *kobj,
++ struct kobj_attribute *attr, const char *buf,
++ size_t count)
++{
++ int result, err;
++ u32 disable;
++
++ err = kstrtou32(buf, 10, &disable);
++ if (err)
++ return err;
++
++ if (disable > 1)
++ return -EINVAL;
++
++ if (asus_armoury.gpu_mux_dev_id) {
++ err = asus_wmi_get_devstate_dsts(asus_armoury.gpu_mux_dev_id, &result);
++ if (err)
++ return err;
++ if (!result && disable) {
++ err = -ENODEV;
++ pr_warn("Can not disable dGPU when the MUX is in dGPU mode: %d\n", err);
++ return err;
++ }
++ // TODO: handle a > 1 result, shouold do a PCI rescan and run again
++ }
++
++ err = armoury_wmi_set_devstate(attr, disable, ASUS_WMI_DEVID_DGPU);
++ if (err)
++ return err;
++
++ sysfs_notify(kobj, NULL, attr->attr.name);
++
++ return count;
++}
++WMI_SHOW_INT(dgpu_disable_current_value, "%d\n", ASUS_WMI_DEVID_DGPU);
++ATTR_GROUP_BOOL_CUSTOM(dgpu_disable, "dgpu_disable", "Disable the dGPU");
++
++/* The ACPI call to enable the eGPU also disables the internal dGPU */
++static ssize_t egpu_enable_current_value_store(struct kobject *kobj, struct kobj_attribute *attr,
++ const char *buf, size_t count)
++{
++ int result, err;
++ u32 enable;
++
++ err = kstrtou32(buf, 10, &enable);
++ if (err)
++ return err;
++
++ if (enable > 1)
++ return -EINVAL;
++
++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_EGPU_CONNECTED, &result);
++ if (err) {
++ pr_warn("Failed to get eGPU connection status: %d\n", err);
++ return err;
++ }
++
++ if (asus_armoury.gpu_mux_dev_id) {
++ err = asus_wmi_get_devstate_dsts(asus_armoury.gpu_mux_dev_id, &result);
++ if (err) {
++ pr_warn("Failed to get GPU MUX status: %d\n", result);
++ return result;
++ }
++ if (!result && enable) {
++ err = -ENODEV;
++ pr_warn("Can not enable eGPU when the MUX is in dGPU mode: %d\n", err);
++ return err;
++ }
++ }
++
++ err = armoury_wmi_set_devstate(attr, enable, ASUS_WMI_DEVID_EGPU);
++ if (err)
++ return err;
++
++ sysfs_notify(kobj, NULL, attr->attr.name);
++
++ return count;
++}
++WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU);
++ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)");
++
++/* Simple attribute creation */
++ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, "0;1;2",
++ "Show the current mode of charging");
++
++ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND,
++ "Set the boot POST sound");
++ATTR_GROUP_BOOL_RW(mcu_powersave, "mcu_powersave", ASUS_WMI_DEVID_MCU_POWERSAVE,
++ "Set MCU powersaving mode");
++ATTR_GROUP_BOOL_RW(panel_od, "panel_overdrive", ASUS_WMI_DEVID_PANEL_OD,
++ "Set the panel refresh overdrive");
++ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED,
++ "Show the eGPU connection status");
++
++/* If an attribute does not require any special case handling add it here */
++static const struct asus_attr_group armoury_attr_groups[] = {
++ { &egpu_connected_attr_group, ASUS_WMI_DEVID_EGPU_CONNECTED },
++ { &egpu_enable_attr_group, ASUS_WMI_DEVID_EGPU },
++ { &dgpu_disable_attr_group, ASUS_WMI_DEVID_DGPU },
++
++ { &charge_mode_attr_group, ASUS_WMI_DEVID_CHARGE_MODE },
++ { &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND },
++ { &mcu_powersave_attr_group, ASUS_WMI_DEVID_MCU_POWERSAVE },
++ { &panel_od_attr_group, ASUS_WMI_DEVID_PANEL_OD },
++};
++
++static int asus_fw_attr_add(void)
++{
++ int err, i;
++
++ err = fw_attributes_class_get(&fw_attr_class);
++ if (err)
++ return err;
++
++ asus_armoury.fw_attr_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0),
++ NULL, "%s", DRIVER_NAME);
++ if (IS_ERR(asus_armoury.fw_attr_dev)) {
++ err = PTR_ERR(asus_armoury.fw_attr_dev);
++ goto fail_class_get;
++ }
++
++ asus_armoury.fw_attr_kset = kset_create_and_add("attributes", NULL,
++ &asus_armoury.fw_attr_dev->kobj);
++ if (!asus_armoury.fw_attr_kset) {
++ err = -ENOMEM;
++ goto err_destroy_classdev;
++ }
++
++ err = sysfs_create_file(&asus_armoury.fw_attr_kset->kobj, &pending_reboot.attr);
++ if (err) {
++ pr_err("Failed to create sysfs level attributes\n");
++ goto err_destroy_kset;
++ }
++
++ asus_armoury.mini_led_dev_id = 0;
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_MINI_LED_MODE)) {
++ asus_armoury.mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;
++ } else if (asus_wmi_is_present(ASUS_WMI_DEVID_MINI_LED_MODE2)) {
++ asus_armoury.mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2;
++ }
++
++ if (asus_armoury.mini_led_dev_id) {
++ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &mini_led_mode_attr_group);
++ if (err) {
++ pr_err("Failed to create sysfs-group for mini_led\n");
++ goto err_remove_file;
++ }
++ }
++
++ asus_armoury.gpu_mux_dev_id = 0;
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_GPU_MUX)) {
++ asus_armoury.gpu_mux_dev_id = ASUS_WMI_DEVID_GPU_MUX;
++ } else if (asus_wmi_is_present(ASUS_WMI_DEVID_GPU_MUX_VIVO)) {
++ asus_armoury.gpu_mux_dev_id = ASUS_WMI_DEVID_GPU_MUX_VIVO;
++ }
++
++ if (asus_armoury.gpu_mux_dev_id) {
++ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &gpu_mux_mode_attr_group);
++ if (err) {
++ pr_err("Failed to create sysfs-group for gpu_mux\n");
++ goto err_remove_mini_led_group;
++ }
++ }
++
++ for (i = 0; i < ARRAY_SIZE(armoury_attr_groups); i++) {
++ if (!asus_wmi_is_present(armoury_attr_groups[i].wmi_devid))
++ continue;
++
++ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj,
++ armoury_attr_groups[i].attr_group);
++ if (err) {
++ pr_err("Failed to create sysfs-group for %s\n",
++ armoury_attr_groups[i].attr_group->name);
++ goto err_remove_groups;
++ }
++ }
++
++ return 0;
++
++err_remove_groups:
++ while (--i >= 0) {
++ if (asus_wmi_is_present(armoury_attr_groups[i].wmi_devid))
++ sysfs_remove_group(&asus_armoury.fw_attr_kset->kobj, armoury_attr_groups[i].attr_group);
++ }
++ sysfs_remove_group(&asus_armoury.fw_attr_kset->kobj, &gpu_mux_mode_attr_group);
++err_remove_mini_led_group:
++ sysfs_remove_group(&asus_armoury.fw_attr_kset->kobj, &mini_led_mode_attr_group);
++err_remove_file:
++ sysfs_remove_file(&asus_armoury.fw_attr_kset->kobj, &pending_reboot.attr);
++err_destroy_kset:
++ kset_unregister(asus_armoury.fw_attr_kset);
++err_destroy_classdev:
++ device_destroy(fw_attr_class, MKDEV(0, 0));
++fail_class_get:
++ fw_attributes_class_put();
++ return err;
++}
++
++/* Init / exit ****************************************************************/
++
++static int __init asus_fw_init(void)
++{
++ char *wmi_uid;
++ int err;
++
++ wmi_uid = wmi_get_acpi_device_uid(ASUS_WMI_MGMT_GUID);
++ if (!wmi_uid)
++ return -ENODEV;
++
++ /*
++ * if equal to "ASUSWMI" then it's DCTS that can't be used for this
++ * driver, DSTS is required.
++ */
++ if (!strcmp(wmi_uid, ASUS_ACPI_UID_ASUSWMI))
++ return -ENODEV;
++
++ err = asus_fw_attr_add();
++ if (err)
++ return err;
++
++ return 0;
++}
++
++static void __exit asus_fw_exit(void)
++{
++ mutex_lock(&asus_armoury.mutex);
++
++ sysfs_remove_file(&asus_armoury.fw_attr_kset->kobj, &pending_reboot.attr);
++ kset_unregister(asus_armoury.fw_attr_kset);
++ device_destroy(fw_attr_class, MKDEV(0, 0));
++ fw_attributes_class_put();
++
++ mutex_unlock(&asus_armoury.mutex);
++}
++
++module_init(asus_fw_init);
++module_exit(asus_fw_exit);
++
++MODULE_IMPORT_NS(ASUS_WMI);
++MODULE_AUTHOR("Luke Jones ");
++MODULE_DESCRIPTION("ASUS BIOS Configuration Driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("wmi:" ASUS_NB_WMI_EVENT_GUID);
+diff --git a/drivers/platform/x86/asus-armoury.h b/drivers/platform/x86/asus-armoury.h
+new file mode 100644
+index 000000000000..b00d829c9da0
+--- /dev/null
++++ b/drivers/platform/x86/asus-armoury.h
+@@ -0,0 +1,147 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Definitions for kernel modules using asus-armoury driver
++ *
++ * Copyright (c) 2024 Luke Jones
++ */
++
++#ifndef _ASUS_ARMOURY_H_
++#define _ASUS_ARMOURY_H_
++
++#include
++#include
++
++#define DRIVER_NAME "asus-armoury"
++
++static ssize_t attr_uint_store(struct kobject *kobj, struct kobj_attribute *attr,
++ const char *buf, size_t count, u32 min, u32 max,
++ u32 *store_value, u32 wmi_dev);
++
++static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr,
++ char *buf)
++{
++ return sysfs_emit(buf, "enumeration\n");
++}
++
++#define __ASUS_ATTR_RO(_func, _name) \
++ { \
++ .attr = { .name = __stringify(_name), .mode = 0444 }, \
++ .show = _func##_##_name##_show, \
++ }
++
++#define __ASUS_ATTR_RO_AS(_name, _show) \
++ { \
++ .attr = { .name = __stringify(_name), .mode = 0444 }, \
++ .show = _show, \
++ }
++
++#define __ASUS_ATTR_RW(_func, _name) \
++ __ATTR(_name, 0644, _func##_##_name##_show, _func##_##_name##_store)
++
++#define __WMI_STORE_INT(_attr, _min, _max, _wmi) \
++ static ssize_t _attr##_store(struct kobject *kobj, \
++ struct kobj_attribute *attr, \
++ const char *buf, size_t count) \
++ { \
++ return attr_uint_store(kobj, attr, buf, count, _min, _max, \
++ NULL, _wmi); \
++ }
++
++#define WMI_SHOW_INT(_attr, _fmt, _wmi) \
++ static ssize_t _attr##_show(struct kobject *kobj, \
++ struct kobj_attribute *attr, char *buf) \
++ { \
++ u32 result; \
++ int err; \
++ \
++ err = asus_wmi_get_devstate_dsts(_wmi, &result); \
++ if (err) \
++ return err; \
++ return sysfs_emit(buf, _fmt, \
++ result & ~ASUS_WMI_DSTS_PRESENCE_BIT); \
++ }
++
++/* Create functions and attributes for use in other macros or on their own */
++
++#define __ATTR_CURRENT_INT_RO(_attr, _wmi) \
++ WMI_SHOW_INT(_attr##_current_value, "%d\n", _wmi); \
++ static struct kobj_attribute attr_##_attr##_current_value = \
++ __ASUS_ATTR_RO(_attr, current_value)
++
++#define __ATTR_CURRENT_INT_RW(_attr, _minv, _maxv, _wmi) \
++ __WMI_STORE_INT(_attr##_current_value, _minv, _maxv, _wmi); \
++ WMI_SHOW_INT(_attr##_current_value, "%d\n", _wmi); \
++ static struct kobj_attribute attr_##_attr##_current_value = \
++ __ASUS_ATTR_RW(_attr, current_value)
++
++/* Shows a formatted static variable */
++#define __ATTR_SHOW_FMT(_prop, _attrname, _fmt, _val) \
++ static ssize_t _attrname##_##_prop##_show( \
++ struct kobject *kobj, struct kobj_attribute *attr, char *buf) \
++ { \
++ return sysfs_emit(buf, _fmt, _val); \
++ } \
++ static struct kobj_attribute attr_##_attrname##_##_prop = \
++ __ASUS_ATTR_RO(_attrname, _prop)
++
++/* Boolean style enumeration, base macro. Requires adding show/store */
++#define __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname) \
++ __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
++ __ATTR_SHOW_FMT(possible_values, _attrname, "%s\n", _possible); \
++ static struct kobj_attribute attr_##_attrname##_type = \
++ __ASUS_ATTR_RO_AS(type, enum_type_show); \
++ static struct attribute *_attrname##_attrs[] = { \
++ &attr_##_attrname##_current_value.attr, \
++ &attr_##_attrname##_display_name.attr, \
++ &attr_##_attrname##_possible_values.attr, \
++ &attr_##_attrname##_type.attr, \
++ NULL \
++ }; \
++ static const struct attribute_group _attrname##_attr_group = { \
++ .name = _fsname, .attrs = _attrname##_attrs \
++ }
++
++#define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \
++ __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
++ __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
++
++#define ATTR_GROUP_BOOL_RW(_attrname, _fsname, _wmi, _dispname) \
++ __ATTR_CURRENT_INT_RW(_attrname, 0, 1, _wmi); \
++ __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
++
++/*
++ * Requires _current_value_show(), _current_value_show()
++ */
++#define ATTR_GROUP_BOOL_CUSTOM(_attrname, _fsname, _dispname) \
++ static struct kobj_attribute attr_##_attrname##_current_value = \
++ __ASUS_ATTR_RW(_attrname, current_value); \
++ __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
++
++#define ATTR_GROUP_ENUM_INT_RO(_attrname, _fsname, _wmi, _possible, _dispname) \
++ __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
++ __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname)
++
++/*
++ * Requires _current_value_show(), _current_value_show()
++ * and _possible_values_show()
++ */
++#define ATTR_GROUP_ENUM_CUSTOM(_attrname, _fsname, _dispname) \
++ __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
++ static struct kobj_attribute attr_##_attrname##_current_value = \
++ __ASUS_ATTR_RW(_attrname, current_value); \
++ static struct kobj_attribute attr_##_attrname##_possible_values = \
++ __ASUS_ATTR_RO(_attrname, possible_values); \
++ static struct kobj_attribute attr_##_attrname##_type = \
++ __ASUS_ATTR_RO_AS(type, enum_type_show); \
++ static struct attribute *_attrname##_attrs[] = { \
++ &attr_##_attrname##_current_value.attr, \
++ &attr_##_attrname##_display_name.attr, \
++ &attr_##_attrname##_possible_values.attr, \
++ &attr_##_attrname##_type.attr, \
++ NULL \
++ }; \
++ static const struct attribute_group _attrname##_attr_group = { \
++ .name = _fsname, .attrs = _attrname##_attrs \
++ }
++
++#endif /* _ASUS_BIOSCFG_H_ */
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index 6da2c7715a9f..525629097b9f 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -55,8 +55,6 @@ module_param(fnlock_default, bool, 0444);
+ #define to_asus_wmi_driver(pdrv) \
+ (container_of((pdrv), struct asus_wmi_driver, platform_driver))
+
+-#define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
+-
+ #define NOTIFY_BRNUP_MIN 0x11
+ #define NOTIFY_BRNUP_MAX 0x1f
+ #define NOTIFY_BRNDOWN_MIN 0x20
+@@ -105,8 +103,6 @@ module_param(fnlock_default, bool, 0444);
+ #define USB_INTEL_XUSB2PR 0xD0
+ #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
+
+-#define ASUS_ACPI_UID_ASUSWMI "ASUSWMI"
+-
+ #define WMI_EVENT_MASK 0xFFFF
+
+ #define FAN_CURVE_POINTS 8
+diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
+index 6ea4dedfb85e..21313e1eb6c9 100644
+--- a/include/linux/platform_data/x86/asus-wmi.h
++++ b/include/linux/platform_data/x86/asus-wmi.h
+@@ -6,6 +6,9 @@
+ #include
+ #include
+
++#define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
++#define ASUS_ACPI_UID_ASUSWMI "ASUSWMI"
++
+ /* WMI Methods */
+ #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
+ #define ASUS_WMI_METHODID_SFBD 0x44424653 /* Set First Boot Device */
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0007-acpi-x86-s2idle-add-support-for-screen-off-and-scree.patch b/packages/l/linux-current/files/patches/hardware/asus/0007-acpi-x86-s2idle-add-support-for-screen-off-and-scree.patch
deleted file mode 100644
index 2c49aa06dc2..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0007-acpi-x86-s2idle-add-support-for-screen-off-and-scree.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mario Limonciello
-Date: Wed, 14 Aug 2024 12:50:25 -0500
-Subject: [PATCH 07/18] acpi/x86: s2idle: add support for screen off and screen
- on callbacks
-
-All the _DSM methods for the LPS0 method are called back to back
-currently. The intended use of the screen off and screen on calls is
-supposed to be matching the screen being turned on or off though.
-Add support for other parts of the kernel to call such a callback.
-
-Signed-off-by: Mario Limonciello
----
- include/linux/suspend.h | 8 ++++++++
- kernel/power/suspend.c | 12 ++++++++++++
- 2 files changed, 20 insertions(+)
-
-diff --git a/include/linux/suspend.h b/include/linux/suspend.h
-index da6ebca3ff77..4535ae82363c 100644
---- a/include/linux/suspend.h
-+++ b/include/linux/suspend.h
-@@ -133,6 +133,8 @@ struct platform_suspend_ops {
-
- struct platform_s2idle_ops {
- int (*begin)(void);
-+ int (*screen_off)(void);
-+ int (*screen_on)(void);
- int (*prepare)(void);
- int (*prepare_late)(void);
- void (*check)(void);
-@@ -160,6 +162,9 @@ extern unsigned int pm_suspend_global_flags;
- #define PM_SUSPEND_FLAG_FW_RESUME BIT(1)
- #define PM_SUSPEND_FLAG_NO_PLATFORM BIT(2)
-
-+int platform_suspend_screen_off(void);
-+int platform_suspend_screen_on(void);
-+
- static inline void pm_suspend_clear_flags(void)
- {
- pm_suspend_global_flags = 0;
-@@ -296,6 +301,9 @@ static inline bool idle_should_enter_s2idle(void) { return false; }
- static inline void __init pm_states_init(void) {}
- static inline void s2idle_set_ops(const struct platform_s2idle_ops *ops) {}
- static inline void s2idle_wake(void) {}
-+static inline int platform_suspend_screen_off(void) { return -ENODEV };
-+static inline int platform_suspend_screen_on(void) { return -ENODEV };
-+
- #endif /* !CONFIG_SUSPEND */
-
- /* struct pbe is used for creating lists of pages that should be restored
-diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
-index 09f8397bae15..19734b297527 100644
---- a/kernel/power/suspend.c
-+++ b/kernel/power/suspend.c
-@@ -254,6 +254,18 @@ static bool sleep_state_supported(suspend_state_t state)
- (valid_state(state) && !cxl_mem_active());
- }
-
-+int platform_suspend_screen_off(void)
-+{
-+ return s2idle_ops && s2idle_ops->screen_off ? s2idle_ops->screen_off() : 0;
-+}
-+EXPORT_SYMBOL_GPL(platform_suspend_screen_off);
-+
-+int platform_suspend_screen_on(void)
-+{
-+ return s2idle_ops && s2idle_ops->screen_on ? s2idle_ops->screen_on() : 0;
-+}
-+EXPORT_SYMBOL_GPL(platform_suspend_screen_on);
-+
- static int platform_suspend_prepare(suspend_state_t state)
- {
- return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare ?
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0007-platform-x86-asus-armoury-add-panel_hd_mode-attribut.patch b/packages/l/linux-current/files/patches/hardware/asus/0007-platform-x86-asus-armoury-add-panel_hd_mode-attribut.patch
new file mode 100644
index 00000000000..0928128bb79
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0007-platform-x86-asus-armoury-add-panel_hd_mode-attribut.patch
@@ -0,0 +1,58 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Thu, 19 Sep 2024 17:23:35 +1200
+Subject: [PATCH 07/27] platform/x86: asus-armoury: add panel_hd_mode attribute
+
+Add panel_hd_mode to toggle the panel mode between single and high
+definition modes.
+
+Signed-off-by: Luke D. Jones
+Reviewed-by: Mario Limonciello
+---
+ drivers/platform/x86/asus-armoury.c | 6 +++++-
+ include/linux/platform_data/x86/asus-wmi.h | 1 +
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
+index 0dd0af6c97e4..e6bfb98420dd 100644
+--- a/drivers/platform/x86/asus-armoury.c
++++ b/drivers/platform/x86/asus-armoury.c
+@@ -107,7 +107,8 @@ static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
+
+ static bool asus_bios_requires_reboot(struct kobj_attribute *attr)
+ {
+- return !strcmp(attr->attr.name, "gpu_mux_mode");
++ return !strcmp(attr->attr.name, "gpu_mux_mode") ||
++ !strcmp(attr->attr.name, "panel_hd_mode");
+ }
+
+ static int armoury_wmi_set_devstate(struct kobj_attribute *attr, u32 value, u32 wmi_dev)
+@@ -419,6 +420,8 @@ ATTR_GROUP_BOOL_RW(mcu_powersave, "mcu_powersave", ASUS_WMI_DEVID_MCU_POWERSAVE,
+ "Set MCU powersaving mode");
+ ATTR_GROUP_BOOL_RW(panel_od, "panel_overdrive", ASUS_WMI_DEVID_PANEL_OD,
+ "Set the panel refresh overdrive");
++ATTR_GROUP_BOOL_RW(panel_hd_mode, "panel_hd_mode", ASUS_WMI_DEVID_PANEL_HD,
++ "Set the panel HD mode to UHD<0> or FHD<1>");
+ ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED,
+ "Show the eGPU connection status");
+
+@@ -432,6 +435,7 @@ static const struct asus_attr_group armoury_attr_groups[] = {
+ { &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND },
+ { &mcu_powersave_attr_group, ASUS_WMI_DEVID_MCU_POWERSAVE },
+ { &panel_od_attr_group, ASUS_WMI_DEVID_PANEL_OD },
++ { &panel_hd_mode_attr_group, ASUS_WMI_DEVID_PANEL_HD },
+ };
+
+ static int asus_fw_attr_add(void)
+diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
+index 21313e1eb6c9..a6064995c2cc 100644
+--- a/include/linux/platform_data/x86/asus-wmi.h
++++ b/include/linux/platform_data/x86/asus-wmi.h
+@@ -76,6 +76,7 @@
+ #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019
+
+ /* Misc */
++#define ASUS_WMI_DEVID_PANEL_HD 0x0005001C
+ #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
+ #define ASUS_WMI_DEVID_CAMERA 0x00060013
+ #define ASUS_WMI_DEVID_LID_FLIP 0x00060062
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0008-drm-Notify-the-suspend-core-when-displays-are-change.patch b/packages/l/linux-current/files/patches/hardware/asus/0008-drm-Notify-the-suspend-core-when-displays-are-change.patch
deleted file mode 100644
index b4684c2faeb..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0008-drm-Notify-the-suspend-core-when-displays-are-change.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mario Limonciello
-Date: Wed, 14 Aug 2024 20:19:09 -0500
-Subject: [PATCH 08/18] drm: Notify the suspend core when displays are changed
- at suspend
-
-This allows notifying the BIOS with the LPS0 _DSM for "Screen off"
-and "Screen on".
-
-Signed-off-by: Mario Limonciello
----
- drivers/gpu/drm/drm_atomic_helper.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
-index fb97b51b38f1..d3ef199c58c1 100644
---- a/drivers/gpu/drm/drm_atomic_helper.c
-+++ b/drivers/gpu/drm/drm_atomic_helper.c
-@@ -27,6 +27,7 @@
-
- #include
- #include
-+#include
-
- #include
- #include
-@@ -3530,6 +3531,13 @@ struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
- goto unlock;
- }
-
-+ err = platform_suspend_screen_off();
-+ if (err < 0) {
-+ drm_atomic_state_put(state);
-+ state = ERR_PTR(err);
-+ goto unlock;
-+ }
-+
- unlock:
- DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
- if (err)
-@@ -3611,7 +3619,12 @@ int drm_atomic_helper_resume(struct drm_device *dev,
- DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err);
-
- err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
-+ if (err < 0)
-+ goto unlock;
-
-+ err = platform_suspend_screen_on();
-+
-+unlock:
- DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
- drm_atomic_state_put(state);
-
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0008-platform-x86-asus-armoury-add-the-ppt_-and-nv_-tunin.patch b/packages/l/linux-current/files/patches/hardware/asus/0008-platform-x86-asus-armoury-add-the-ppt_-and-nv_-tunin.patch
new file mode 100644
index 00000000000..675361b8ca9
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0008-platform-x86-asus-armoury-add-the-ppt_-and-nv_-tunin.patch
@@ -0,0 +1,277 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Thu, 19 Sep 2024 17:19:37 +1200
+Subject: [PATCH 08/27] platform/x86: asus-armoury: add the ppt_* and nv_*
+ tuning knobs
+
+Adds the ppt_* and nv_* tuning knobs that are available via WMI methods
+and adds proper min/max levels plus defaults.
+
+Signed-off-by: Luke D. Jones
+Reviewed-by: Mario Limonciello
+---
+ drivers/platform/x86/asus-armoury.c | 135 ++++++++++++++++++++++++++++
+ drivers/platform/x86/asus-armoury.h | 65 ++++++++++++++
+ 2 files changed, 200 insertions(+)
+
+diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
+index e6bfb98420dd..18b911040e57 100644
+--- a/drivers/platform/x86/asus-armoury.c
++++ b/drivers/platform/x86/asus-armoury.c
+@@ -52,12 +52,40 @@
+ #define PPT_PLATFORM_MAX 100
+ #define PPT_PLATFORM_DEFAULT 80
+
++/* Tunables provided by ASUS for gaming laptops */
++struct rog_tunables {
++ u32 cpu_default;
++ u32 cpu_min;
++ u32 cpu_max;
++
++ u32 platform_default;
++ u32 platform_min;
++ u32 platform_max;
++
++ u32 ppt_pl1_spl; // cpu
++ u32 ppt_pl2_sppt; // cpu
++ u32 ppt_apu_sppt; // plat
++ u32 ppt_platform_sppt; // plat
++ u32 ppt_fppt; // cpu
++
++ u32 nv_boost_default;
++ u32 nv_boost_min;
++ u32 nv_boost_max;
++ u32 nv_dynamic_boost;
++
++ u32 nv_temp_default;
++ u32 nv_temp_min;
++ u32 nv_temp_max;
++ u32 nv_temp_target;
++};
++
+ static const struct class *fw_attr_class;
+
+ struct asus_armoury_priv {
+ struct device *fw_attr_dev;
+ struct kset *fw_attr_kset;
+
++ struct rog_tunables *rog_tunables;
+ u32 mini_led_dev_id;
+ u32 gpu_mux_dev_id;
+
+@@ -411,6 +439,25 @@ WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU);
+ ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)");
+
+ /* Simple attribute creation */
++ATTR_GROUP_ROG_TUNABLE(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL, cpu_default,
++ cpu_min, cpu_max, 1, "Set the CPU slow package limit");
++ATTR_GROUP_ROG_TUNABLE(ppt_pl2_sppt, "ppt_pl2_sppt", ASUS_WMI_DEVID_PPT_PL2_SPPT, cpu_default,
++ cpu_min, cpu_max, 1, "Set the CPU fast package limit");
++ATTR_GROUP_ROG_TUNABLE(ppt_apu_sppt, "ppt_apu_sppt", ASUS_WMI_DEVID_PPT_APU_SPPT,
++ platform_default, platform_min, platform_max, 1,
++ "Set the CPU slow package limit");
++ATTR_GROUP_ROG_TUNABLE(ppt_platform_sppt, "ppt_platform_sppt", ASUS_WMI_DEVID_PPT_PLAT_SPPT,
++ platform_default, platform_min, platform_max, 1,
++ "Set the CPU slow package limit");
++ATTR_GROUP_ROG_TUNABLE(ppt_fppt, "ppt_fppt", ASUS_WMI_DEVID_PPT_FPPT, cpu_default, cpu_min,
++ cpu_max, 1, "Set the CPU slow package limit");
++ATTR_GROUP_ROG_TUNABLE(nv_dynamic_boost, "nv_dynamic_boost", ASUS_WMI_DEVID_NV_DYN_BOOST,
++ nv_boost_default, nv_boost_min, nv_boost_max, 1,
++ "Set the Nvidia dynamic boost limit");
++ATTR_GROUP_ROG_TUNABLE(nv_temp_target, "nv_temp_target", ASUS_WMI_DEVID_NV_THERM_TARGET,
++ nv_temp_default, nv_boost_min, nv_temp_max, 1,
++ "Set the Nvidia max thermal limit");
++
+ ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, "0;1;2",
+ "Show the current mode of charging");
+
+@@ -431,6 +478,14 @@ static const struct asus_attr_group armoury_attr_groups[] = {
+ { &egpu_enable_attr_group, ASUS_WMI_DEVID_EGPU },
+ { &dgpu_disable_attr_group, ASUS_WMI_DEVID_DGPU },
+
++ { &ppt_pl1_spl_attr_group, ASUS_WMI_DEVID_PPT_PL1_SPL },
++ { &ppt_pl2_sppt_attr_group, ASUS_WMI_DEVID_PPT_PL2_SPPT },
++ { &ppt_apu_sppt_attr_group, ASUS_WMI_DEVID_PPT_APU_SPPT },
++ { &ppt_platform_sppt_attr_group, ASUS_WMI_DEVID_PPT_PLAT_SPPT },
++ { &ppt_fppt_attr_group, ASUS_WMI_DEVID_PPT_FPPT },
++ { &nv_dynamic_boost_attr_group, ASUS_WMI_DEVID_NV_DYN_BOOST },
++ { &nv_temp_target_attr_group, ASUS_WMI_DEVID_NV_THERM_TARGET },
++
+ { &charge_mode_attr_group, ASUS_WMI_DEVID_CHARGE_MODE },
+ { &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND },
+ { &mcu_powersave_attr_group, ASUS_WMI_DEVID_MCU_POWERSAVE },
+@@ -532,6 +587,80 @@ static int asus_fw_attr_add(void)
+
+ /* Init / exit ****************************************************************/
+
++/* Set up the min/max and defaults for ROG tunables */
++static void init_rog_tunables(struct rog_tunables *rog)
++{
++ u32 platform_default = PPT_PLATFORM_DEFAULT;
++ u32 cpu_default = PPT_CPU_LIMIT_DEFAULT;
++ u32 platform_max = PPT_PLATFORM_MAX;
++ u32 max_boost = NVIDIA_BOOST_MAX;
++ u32 cpu_max = PPT_CPU_LIMIT_MAX;
++ const char *product;
++
++ /*
++ * ASUS product_name contains everything required, e.g,
++ * "ROG Flow X16 GV601VV_GV601VV_00185149B".
++ * The bulk of these defaults are gained from users reporting what
++ * ASUS Armoury Crate in Windows provides them.
++ * This should be turned in to a table eventually.
++ */
++ product = dmi_get_system_info(DMI_PRODUCT_NAME);
++
++ if (strstr(product, "GA402R")) {
++ cpu_default = 125;
++ } else if (strstr(product, "13QY")) {
++ cpu_max = 250;
++ } else if (strstr(product, "X13")) {
++ cpu_max = 75;
++ cpu_default = 50;
++ } else if (strstr(product, "RC71") || strstr(product, "RC72")) {
++ cpu_max = 50;
++ cpu_default = 30;
++ } else if (strstr(product, "G814") || strstr(product, "G614") ||
++ strstr(product, "G834") || strstr(product, "G634")) {
++ cpu_max = 175;
++ } else if (strstr(product, "GA402X") || strstr(product, "GA403") ||
++ strstr(product, "FA507N") || strstr(product, "FA507X") ||
++ strstr(product, "FA707N") || strstr(product, "FA707X")) {
++ cpu_max = 90;
++ } else {
++ pr_notice("Using default CPU limits. Please report if these are not correct.\n");
++ }
++
++ if (strstr(product, "GZ301ZE"))
++ max_boost = 5;
++ else if (strstr(product, "FX507ZC4"))
++ max_boost = 15;
++ else if (strstr(product, "GU605"))
++ max_boost = 20;
++
++ /* ensure defaults for tunables */
++ rog->cpu_default = cpu_default;
++ rog->cpu_min = PPT_CPU_LIMIT_MIN;
++ rog->cpu_max = cpu_max;
++
++ rog->platform_default = platform_default;
++ rog->platform_max = PPT_PLATFORM_MIN;
++ rog->platform_max = platform_max;
++
++ rog->ppt_pl1_spl = cpu_default;
++ rog->ppt_pl2_sppt = cpu_default;
++ rog->ppt_apu_sppt = cpu_default;
++
++ rog->ppt_platform_sppt = platform_default;
++ rog->ppt_fppt = cpu_default;
++
++ rog->nv_boost_default = NVIDIA_BOOST_MAX;
++ rog->nv_boost_min = NVIDIA_BOOST_MIN;
++ rog->nv_boost_max = max_boost;
++ rog->nv_dynamic_boost = NVIDIA_BOOST_MIN;
++
++ rog->nv_temp_default = NVIDIA_TEMP_MAX;
++ rog->nv_temp_min = NVIDIA_TEMP_MIN;
++ rog->nv_temp_max = NVIDIA_TEMP_MAX;
++ rog->nv_temp_target = NVIDIA_TEMP_MIN;
++}
++
+ static int __init asus_fw_init(void)
+ {
+ char *wmi_uid;
+@@ -548,6 +677,12 @@ static int __init asus_fw_init(void)
+ if (!strcmp(wmi_uid, ASUS_ACPI_UID_ASUSWMI))
+ return -ENODEV;
+
++ asus_armoury.rog_tunables = kzalloc(sizeof(struct rog_tunables), GFP_KERNEL);
++ if (!asus_armoury.rog_tunables)
++ return -ENOMEM;
++
++ init_rog_tunables(asus_armoury.rog_tunables);
++
+ err = asus_fw_attr_add();
+ if (err)
+ return err;
+diff --git a/drivers/platform/x86/asus-armoury.h b/drivers/platform/x86/asus-armoury.h
+index b00d829c9da0..91ec6f4cb149 100644
+--- a/drivers/platform/x86/asus-armoury.h
++++ b/drivers/platform/x86/asus-armoury.h
+@@ -17,6 +17,12 @@ static ssize_t attr_uint_store(struct kobject *kobj, struct kobj_attribute *attr
+ const char *buf, size_t count, u32 min, u32 max,
+ u32 *store_value, u32 wmi_dev);
+
++static ssize_t int_type_show(struct kobject *kobj, struct kobj_attribute *attr,
++ char *buf)
++{
++ return sysfs_emit(buf, "integer\n");
++}
++
+ static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+ {
+@@ -144,4 +150,63 @@ static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr,
+ .name = _fsname, .attrs = _attrname##_attrs \
+ }
+
++/*
++ * ROG PPT attributes need a little different in setup as they
++ * require rog_tunables members.
++ */
++
++#define __ROG_TUNABLE_RW(_attr, _min, _max, _wmi) \
++ static ssize_t _attr##_current_value_store( \
++ struct kobject *kobj, struct kobj_attribute *attr, \
++ const char *buf, size_t count) \
++ { \
++ return attr_uint_store(kobj, attr, buf, count, \
++ asus_armoury.rog_tunables->_min, \
++ asus_armoury.rog_tunables->_max, \
++ &asus_armoury.rog_tunables->_attr, \
++ _wmi); \
++ } \
++ static ssize_t _attr##_current_value_show( \
++ struct kobject *kobj, struct kobj_attribute *attr, char *buf) \
++ { \
++ return sysfs_emit(buf, "%u\n", \
++ asus_armoury.rog_tunables->_attr); \
++ } \
++ static struct kobj_attribute attr_##_attr##_current_value = \
++ __ASUS_ATTR_RW(_attr, current_value)
++
++#define __ROG_TUNABLE_SHOW(_prop, _attrname, _val) \
++ static ssize_t _attrname##_##_prop##_show( \
++ struct kobject *kobj, struct kobj_attribute *attr, char *buf) \
++ { \
++ return sysfs_emit(buf, "%d\n", \
++ asus_armoury.rog_tunables->_val); \
++ } \
++ static struct kobj_attribute attr_##_attrname##_##_prop = \
++ __ASUS_ATTR_RO(_attrname, _prop)
++
++#define ATTR_GROUP_ROG_TUNABLE(_attrname, _fsname, _wmi, _default, _min, _max, \
++ _incstep, _dispname) \
++ __ROG_TUNABLE_SHOW(default_value, _attrname, _default); \
++ __ROG_TUNABLE_RW(_attrname, _min, _max, _wmi); \
++ __ROG_TUNABLE_SHOW(min_value, _attrname, _min); \
++ __ROG_TUNABLE_SHOW(max_value, _attrname, _max); \
++ __ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", _incstep); \
++ __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
++ static struct kobj_attribute attr_##_attrname##_type = \
++ __ASUS_ATTR_RO_AS(type, int_type_show); \
++ static struct attribute *_attrname##_attrs[] = { \
++ &attr_##_attrname##_current_value.attr, \
++ &attr_##_attrname##_default_value.attr, \
++ &attr_##_attrname##_min_value.attr, \
++ &attr_##_attrname##_max_value.attr, \
++ &attr_##_attrname##_scalar_increment.attr, \
++ &attr_##_attrname##_display_name.attr, \
++ &attr_##_attrname##_type.attr, \
++ NULL \
++ }; \
++ static const struct attribute_group _attrname##_attr_group = { \
++ .name = _fsname, .attrs = _attrname##_attrs \
++ }
++
+ #endif /* _ASUS_BIOSCFG_H_ */
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0009-acpi-x86-s2idle-Move-screen-off-on-code-into-dedicat.patch b/packages/l/linux-current/files/patches/hardware/asus/0009-acpi-x86-s2idle-Move-screen-off-on-code-into-dedicat.patch
deleted file mode 100644
index 36375286076..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0009-acpi-x86-s2idle-Move-screen-off-on-code-into-dedicat.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mario Limonciello
-Date: Wed, 14 Aug 2024 20:20:13 -0500
-Subject: [PATCH 09/18] acpi/x86: s2idle: Move screen off/on code into
- dedicated callbacks
-
-This lets the DRM core notify on screen events instead of calling
-them back to back.
-
-Signed-off-by: Mario Limonciello
----
- drivers/acpi/x86/s2idle.c | 75 ++++++++++++++++++++++++++++++---------
- 1 file changed, 59 insertions(+), 16 deletions(-)
-
-diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
-index dd0b40b9bbe8..e7f9748937d6 100644
---- a/drivers/acpi/x86/s2idle.c
-+++ b/drivers/acpi/x86/s2idle.c
-@@ -539,17 +539,21 @@ static struct acpi_scan_handler lps0_handler = {
- .attach = lps0_device_attach,
- };
-
--int acpi_s2idle_prepare_late(void)
-+static int acpi_s2idle_screen_off(void)
- {
-- struct acpi_s2idle_dev_ops *handler;
--
- if (!lps0_device_handle || sleep_no_lps0)
- return 0;
-
-- if (pm_debug_messages_on)
-- lpi_check_constraints();
-+ switch (lps0_dsm_state) {
-+ case ACPI_LPS0_SCREEN_OFF_AMD:
-+ case ACPI_LPS0_SCREEN_OFF:
-+ if (pm_debug_messages_on)
-+ acpi_handle_info(lps0_device_handle,
-+ "already in %s\n",
-+ acpi_sleep_dsm_state_to_str(lps0_dsm_state));
-+ return 0;
-+ }
-
-- /* Screen off */
- if (lps0_dsm_func_mask > 0)
- acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
- ACPI_LPS0_SCREEN_OFF_AMD :
-@@ -560,6 +564,47 @@ int acpi_s2idle_prepare_late(void)
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-
-+ return 0;
-+}
-+
-+static int acpi_s2idle_screen_on(void)
-+{
-+ if (!lps0_device_handle || sleep_no_lps0)
-+ return 0;
-+
-+ switch (lps0_dsm_state) {
-+ case ACPI_LPS0_SCREEN_ON_AMD:
-+ case ACPI_LPS0_SCREEN_ON:
-+ if (pm_debug_messages_on)
-+ acpi_handle_info(lps0_device_handle,
-+ "already in %s\n",
-+ acpi_sleep_dsm_state_to_str(lps0_dsm_state));
-+ return 0;
-+ }
-+
-+ if (lps0_dsm_func_mask_microsoft > 0)
-+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
-+ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-+
-+ if (lps0_dsm_func_mask > 0)
-+ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-+ ACPI_LPS0_SCREEN_ON_AMD :
-+ ACPI_LPS0_SCREEN_ON,
-+ lps0_dsm_func_mask, lps0_dsm_guid);
-+
-+ return 0;
-+}
-+
-+int acpi_s2idle_prepare_late(void)
-+{
-+ struct acpi_s2idle_dev_ops *handler;
-+
-+ if (!lps0_device_handle || sleep_no_lps0)
-+ return 0;
-+
-+ if (pm_debug_messages_on)
-+ lpi_check_constraints();
-+
- /* LPS0 entry */
- if (lps0_dsm_func_mask > 0 && acpi_s2idle_vendor_amd())
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD,
-@@ -623,20 +668,18 @@ void acpi_s2idle_restore_early(void)
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
- }
-+}
-
-- /* Screen on */
-- if (lps0_dsm_func_mask_microsoft > 0)
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
-- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-- if (lps0_dsm_func_mask > 0)
-- acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-- ACPI_LPS0_SCREEN_ON_AMD :
-- ACPI_LPS0_SCREEN_ON,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-+static int acpi_x86_s2idle_begin(void)
-+{
-+ lps0_dsm_state = -1;
-+ return acpi_s2idle_begin();
- }
-
- static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
-- .begin = acpi_s2idle_begin,
-+ .begin = acpi_x86_s2idle_begin,
-+ .screen_off = acpi_s2idle_screen_off,
-+ .screen_on = acpi_s2idle_screen_on,
- .prepare = acpi_s2idle_prepare,
- .prepare_late = acpi_s2idle_prepare_late,
- .check = acpi_s2idle_check,
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0012-platform-x86-asus-armoury-add-dgpu-tgp-control.patch b/packages/l/linux-current/files/patches/hardware/asus/0009-platform-x86-asus-armoury-add-dgpu-tgp-control.patch
similarity index 53%
rename from packages/l/linux-current/files/patches/hardware/asus/0012-platform-x86-asus-armoury-add-dgpu-tgp-control.patch
rename to packages/l/linux-current/files/patches/hardware/asus/0009-platform-x86-asus-armoury-add-dgpu-tgp-control.patch
index b57c6be8c5e..23705e242bd 100644
--- a/packages/l/linux-current/files/patches/hardware/asus/0012-platform-x86-asus-armoury-add-dgpu-tgp-control.patch
+++ b/packages/l/linux-current/files/patches/hardware/asus/0009-platform-x86-asus-armoury-add-dgpu-tgp-control.patch
@@ -1,32 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones"
Date: Sun, 2 Jun 2024 14:32:15 +1200
-Subject: [PATCH 12/18] platform/x86: asus-armoury: add dgpu tgp control
+Subject: [PATCH 09/27] platform/x86: asus-armoury: add dgpu tgp control
Implement the dgpu TGP control under the asus-armoury module using the
fw_attributes class.
+Reviewed-by: Mario Limonciello
Signed-off-by: Luke D. Jones
---
- drivers/platform/x86/asus-armoury.c | 20 ++++++++++++++++++++
- drivers/platform/x86/asus-armoury.h | 20 ++++++++++++++++++++
+ drivers/platform/x86/asus-armoury.c | 21 +++++++++++++++++++++
+ drivers/platform/x86/asus-armoury.h | 18 ++++++++++++++++++
include/linux/platform_data/x86/asus-wmi.h | 3 +++
- 3 files changed, 43 insertions(+)
+ 3 files changed, 42 insertions(+)
diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
-index 0bbc85170ade..47ade7fcea09 100644
+index 18b911040e57..10ab258855c4 100644
--- a/drivers/platform/x86/asus-armoury.c
+++ b/drivers/platform/x86/asus-armoury.c
-@@ -51,6 +51,9 @@
- #define NVIDIA_BOOST_MAX 25
- #define NVIDIA_TEMP_MIN 75
- #define NVIDIA_TEMP_MAX 87
-+#define NVIDIA_POWER_MIN 0
-+#define NVIDIA_POWER_MAX 70
-+#define NVIDIA_POWER_DEFAULT 70
-
- /* Tunables provided by ASUS for gaming laptops */
- struct rog_tunables {
+@@ -45,6 +45,9 @@
+ #define NVIDIA_BOOST_MAX 25
+ #define NVIDIA_TEMP_MIN 75
+ #define NVIDIA_TEMP_MAX 87
++#define NVIDIA_POWER_MIN 0
++#define NVIDIA_POWER_MAX 70
++#define NVIDIA_POWER_DEFAULT 70
+ #define PPT_CPU_LIMIT_MIN 5
+ #define PPT_CPU_LIMIT_MAX 150
+ #define PPT_CPU_LIMIT_DEFAULT 80
@@ -77,6 +80,11 @@ struct rog_tunables {
u32 nv_temp_min;
u32 nv_temp_max;
@@ -39,19 +40,20 @@ index 0bbc85170ade..47ade7fcea09 100644
};
static const struct class *fw_attr_class;
-@@ -468,6 +476,11 @@ ATTR_GROUP_ROG_TUNABLE(nv_dynamic_boost, "nv_dynamic_boost", ASUS_WMI_DEVID_NV_D
- nv_boost_default, nv_boost_min, nv_boost_max, 1, "Set the Nvidia dynamic boost limit");
+@@ -457,6 +465,12 @@ ATTR_GROUP_ROG_TUNABLE(nv_dynamic_boost, "nv_dynamic_boost", ASUS_WMI_DEVID_NV_D
ATTR_GROUP_ROG_TUNABLE(nv_temp_target, "nv_temp_target", ASUS_WMI_DEVID_NV_THERM_TARGET,
- nv_temp_default, nv_boost_min, nv_temp_max, 1, "Set the Nvidia max thermal limit");
+ nv_temp_default, nv_boost_min, nv_temp_max, 1,
+ "Set the Nvidia max thermal limit");
++ATTR_GROUP_ROG_TUNABLE(dgpu_tgp, "dgpu_tgp", ASUS_WMI_DEVID_DGPU_SET_TGP, dgpu_tgp_default,
++ dgpu_tgp_min, dgpu_tgp_max, 1,
++ "Set the additional TGP on top of the base TGP");
++
+ATTR_GROUP_INT_VALUE_ONLY_RO(dgpu_base_tgp, "dgpu_base_tgp", ASUS_WMI_DEVID_DGPU_BASE_TGP,
-+ "Read the base TGP value");
-+ATTR_GROUP_ROG_TUNABLE(dgpu_tgp, "dgpu_tgp", ASUS_WMI_DEVID_DGPU_SET_TGP,
-+ dgpu_tgp_default, dgpu_tgp_min, dgpu_tgp_max, 1,
-+ "Set the additional TGP on top of the base TGP");
++ "Read the base TGP value");
- ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE,
- "0;1;2", "Show the current mode of charging");
-@@ -495,6 +508,8 @@ static const struct asus_attr_group armoury_attr_groups[] = {
+ ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, "0;1;2",
+ "Show the current mode of charging");
+@@ -485,6 +499,8 @@ static const struct asus_attr_group armoury_attr_groups[] = {
{ &ppt_fppt_attr_group, ASUS_WMI_DEVID_PPT_FPPT },
{ &nv_dynamic_boost_attr_group, ASUS_WMI_DEVID_NV_DYN_BOOST },
{ &nv_temp_target_attr_group, ASUS_WMI_DEVID_NV_THERM_TARGET },
@@ -60,61 +62,59 @@ index 0bbc85170ade..47ade7fcea09 100644
{ &charge_mode_attr_group, ASUS_WMI_DEVID_CHARGE_MODE },
{ &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND },
-@@ -664,6 +679,11 @@ static void init_rog_tunables(struct rog_tunables *rog)
+@@ -659,6 +675,11 @@ static void init_rog_tunables(struct rog_tunables *rog)
+ rog->nv_temp_min = NVIDIA_TEMP_MIN;
rog->nv_temp_max = NVIDIA_TEMP_MAX;
rog->nv_temp_target = NVIDIA_TEMP_MIN;
-
++
+ rog->dgpu_tgp_default = NVIDIA_POWER_DEFAULT;
+ rog->dgpu_tgp_min = NVIDIA_POWER_MIN;
+ rog->dgpu_tgp_max = NVIDIA_POWER_MAX;
+ rog->dgpu_tgp = NVIDIA_POWER_MAX;
-+
}
static int __init asus_fw_init(void)
diff --git a/drivers/platform/x86/asus-armoury.h b/drivers/platform/x86/asus-armoury.h
-index 8a357fb6e071..1652c44c3c9f 100644
+index 91ec6f4cb149..9639e7ca772f 100644
--- a/drivers/platform/x86/asus-armoury.h
+++ b/drivers/platform/x86/asus-armoury.h
-@@ -86,6 +86,22 @@ static ssize_t _attrname##_##_prop##_show(struct kobject *kobj, \
- static struct kobj_attribute attr_##_attrname##_##_prop = \
- __ASUS_ATTR_RO(_attrname, _prop)
+@@ -90,6 +90,20 @@ static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr,
+ static struct kobj_attribute attr_##_attrname##_##_prop = \
+ __ASUS_ATTR_RO(_attrname, _prop)
+/* Requires current_value_show */
-+#define __ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname) \
-+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-+static struct kobj_attribute attr_##_attrname##_type = \
-+ __ASUS_ATTR_RO_AS(type, int_type_show); \
-+static struct attribute *_attrname##_attrs[] = { \
-+ &attr_##_attrname##_current_value.attr, \
-+ &attr_##_attrname##_display_name.attr, \
-+ &attr_##_attrname##_type.attr, \
-+ NULL \
-+}; \
-+static const struct attribute_group _attrname##_attr_group = { \
-+ .name = _fsname, \
-+ .attrs = _attrname##_attrs \
-+}
++#define __ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname) \
++ __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
++ static struct kobj_attribute attr_##_attrname##_type = \
++ __ASUS_ATTR_RO_AS(type, int_type_show); \
++ static struct attribute *_attrname##_attrs[] = { \
++ &attr_##_attrname##_current_value.attr, \
++ &attr_##_attrname##_display_name.attr, \
++ &attr_##_attrname##_type.attr, NULL \
++ }; \
++ static const struct attribute_group _attrname##_attr_group = { \
++ .name = _fsname, .attrs = _attrname##_attrs \
++ }
+
/* Boolean style enumeration, base macro. Requires adding show/store */
- #define __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname) \
- __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-@@ -104,6 +120,10 @@ static const struct attribute_group _attrname##_attr_group = { \
- .attrs = _attrname##_attrs \
- }
+ #define __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname) \
+ __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
+@@ -107,6 +121,10 @@ static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr,
+ .name = _fsname, .attrs = _attrname##_attrs \
+ }
-+#define ATTR_GROUP_INT_VALUE_ONLY_RO(_attrname, _fsname, _wmi, _dispname) \
-+ __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
++#define ATTR_GROUP_INT_VALUE_ONLY_RO(_attrname, _fsname, _wmi, _dispname) \
++ __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
+ __ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname)
+
- #define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \
- __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
+ #define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \
+ __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
__ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 7caf2c7ed8c9..86629e621c61 100644
+index a6064995c2cc..8c755799eb60 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -134,6 +134,9 @@
+@@ -137,6 +137,9 @@
/* dgpu on/off */
#define ASUS_WMI_DEVID_DGPU 0x00090020
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0013-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch b/packages/l/linux-current/files/patches/hardware/asus/0010-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch
similarity index 74%
rename from packages/l/linux-current/files/patches/hardware/asus/0013-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch
rename to packages/l/linux-current/files/patches/hardware/asus/0010-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch
index a72bf9afa12..2648762d488 100644
--- a/packages/l/linux-current/files/patches/hardware/asus/0013-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch
+++ b/packages/l/linux-current/files/patches/hardware/asus/0010-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones"
Date: Sun, 2 Jun 2024 14:44:31 +1200
-Subject: [PATCH 13/18] platform/x86: asus-armoury: add apu-mem control support
+Subject: [PATCH 10/27] platform/x86: asus-armoury: add apu-mem control support
Implement the APU memory size control under the asus-armoury module using
the fw_attributes class.
@@ -10,23 +10,24 @@ This allows the APU allocated memory size to be adjusted depending on
the users priority. A reboot is required after change.
Signed-off-by: Luke D. Jones
+Reviewed-by: Mario Limonciello
---
- drivers/platform/x86/asus-armoury.c | 115 +++++++++++++++++++++
+ drivers/platform/x86/asus-armoury.c | 114 +++++++++++++++++++++
include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 116 insertions(+)
+ 2 files changed, 115 insertions(+)
diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
-index 47ade7fcea09..10764c04232a 100644
+index 10ab258855c4..271dadc4c75d 100644
--- a/drivers/platform/x86/asus-armoury.c
+++ b/drivers/platform/x86/asus-armoury.c
-@@ -460,6 +460,120 @@ static ssize_t egpu_enable_current_value_store(struct kobject *kobj,
+@@ -446,6 +446,119 @@ static ssize_t egpu_enable_current_value_store(struct kobject *kobj, struct kobj
WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU);
ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)");
+/* Device memory available to APU */
+
-+static ssize_t apu_mem_current_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++static ssize_t apu_mem_current_value_show(struct kobject *kobj, struct kobj_attribute *attr,
++ char *buf)
+{
+ int err;
+ u32 mem;
@@ -36,32 +37,32 @@ index 47ade7fcea09..10764c04232a 100644
+ return err;
+
+ switch (mem) {
-+ case 256:
++ case 0x100:
+ mem = 0;
+ break;
-+ case 258:
++ case 0x102:
+ mem = 1;
+ break;
-+ case 259:
++ case 0x103:
+ mem = 2;
+ break;
-+ case 260:
++ case 0x104:
+ mem = 3;
+ break;
-+ case 261:
++ case 0x105:
+ mem = 4;
+ break;
-+ case 262:
++ case 0x106:
+ /* This is out of order and looks wrong but is correct */
+ mem = 8;
+ break;
-+ case 263:
++ case 0x107:
+ mem = 5;
+ break;
-+ case 264:
++ case 0x108:
+ mem = 6;
+ break;
-+ case 265:
++ case 0x109:
+ mem = 7;
+ break;
+ default:
@@ -72,9 +73,8 @@ index 47ade7fcea09..10764c04232a 100644
+ return sysfs_emit(buf, "%u\n", mem);
+}
+
-+static ssize_t apu_mem_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
++static ssize_t apu_mem_current_value_store(struct kobject *kobj, struct kobj_attribute *attr,
++ const char *buf, size_t count)
+{
+ int result, err;
+ u32 requested, mem;
@@ -85,32 +85,32 @@ index 47ade7fcea09..10764c04232a 100644
+
+ switch (requested) {
+ case 0:
-+ mem = 0;
++ mem = 0x000;
+ break;
+ case 1:
-+ mem = 258;
++ mem = 0x102;
+ break;
+ case 2:
-+ mem = 259;
++ mem = 0x103;
+ break;
+ case 3:
-+ mem = 260;
++ mem = 0x104;
+ break;
+ case 4:
-+ mem = 261;
++ mem = 0x105;
+ break;
+ case 5:
-+ mem = 263;
++ mem = 0x107;
+ break;
+ case 6:
-+ mem = 264;
++ mem = 0x108;
+ break;
+ case 7:
-+ mem = 265;
++ mem = 0x109;
+ break;
+ case 8:
+ /* This is out of order and looks wrong but is correct */
-+ mem = 262;
++ mem = 0x106;
+ break;
+ default:
+ return -EIO;
@@ -130,17 +130,17 @@ index 47ade7fcea09..10764c04232a 100644
+ return count;
+}
+
-+static ssize_t apu_mem_possible_values_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++static ssize_t apu_mem_possible_values_show(struct kobject *kobj, struct kobj_attribute *attr,
++ char *buf)
+{
+ return sysfs_emit(buf, "0;1;2;3;4;5;6;7;8\n");
+}
-+ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set the available system memory for the APU to use");
++ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set available system RAM (in GB) for the APU to use");
+
/* Simple attribute creation */
- ATTR_GROUP_ROG_TUNABLE(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL,
- cpu_default, cpu_min, cpu_max, 1, "Set the CPU slow package limit");
-@@ -510,6 +624,7 @@ static const struct asus_attr_group armoury_attr_groups[] = {
+ ATTR_GROUP_ROG_TUNABLE(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL, cpu_default,
+ cpu_min, cpu_max, 1, "Set the CPU slow package limit");
+@@ -501,6 +614,7 @@ static const struct asus_attr_group armoury_attr_groups[] = {
{ &nv_temp_target_attr_group, ASUS_WMI_DEVID_NV_THERM_TARGET },
{ &dgpu_base_tgp_attr_group, ASUS_WMI_DEVID_DGPU_BASE_TGP },
{ &dgpu_tgp_attr_group, ASUS_WMI_DEVID_DGPU_SET_TGP },
@@ -149,10 +149,10 @@ index 47ade7fcea09..10764c04232a 100644
{ &charge_mode_attr_group, ASUS_WMI_DEVID_CHARGE_MODE },
{ &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND },
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 86629e621c61..e1aeafdf05d5 100644
+index 8c755799eb60..88bf250dc8ca 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -136,6 +136,7 @@
+@@ -139,6 +139,7 @@
#define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099
#define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0014-platform-x86-asus-armoury-add-core-count-control.patch b/packages/l/linux-current/files/patches/hardware/asus/0011-platform-x86-asus-armoury-add-core-count-control.patch
similarity index 57%
rename from packages/l/linux-current/files/patches/hardware/asus/0014-platform-x86-asus-armoury-add-core-count-control.patch
rename to packages/l/linux-current/files/patches/hardware/asus/0011-platform-x86-asus-armoury-add-core-count-control.patch
index e29cc00d25d..50e3b1ebc81 100644
--- a/packages/l/linux-current/files/patches/hardware/asus/0014-platform-x86-asus-armoury-add-core-count-control.patch
+++ b/packages/l/linux-current/files/patches/hardware/asus/0011-platform-x86-asus-armoury-add-core-count-control.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones"
-Date: Sun, 2 Jun 2024 16:21:32 +1200
-Subject: [PATCH 14/18] platform/x86: asus-armoury: add core count control
+Date: Wed, 18 Sep 2024 21:19:12 +1200
+Subject: [PATCH 11/27] platform/x86: asus-armoury: add core count control
Implement Intel core enablement under the asus-armoury module using the
fw_attributes class.
@@ -10,19 +10,20 @@ This allows users to enable or disable preformance or efficiency cores
depending on their requirements. After change a reboot is required.
Signed-off-by: Luke D. Jones
+Reviewed-by: Mario Limonciello
---
- drivers/platform/x86/asus-armoury.c | 218 +++++++++++++++++++++
- drivers/platform/x86/asus-armoury.h | 29 +++
+ drivers/platform/x86/asus-armoury.c | 226 +++++++++++++++++++++
+ drivers/platform/x86/asus-armoury.h | 28 +++
include/linux/platform_data/x86/asus-wmi.h | 4 +
- 3 files changed, 251 insertions(+)
+ 3 files changed, 258 insertions(+)
diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
-index 10764c04232a..a445bd6f57a4 100644
+index 271dadc4c75d..69e79446c411 100644
--- a/drivers/platform/x86/asus-armoury.c
+++ b/drivers/platform/x86/asus-armoury.c
-@@ -40,6 +40,21 @@
- #define ASUS_MINI_LED_2024_STRONG 0x01
- #define ASUS_MINI_LED_2024_OFF 0x02
+@@ -40,6 +40,24 @@
+ #define ASUS_MINI_LED_2024_STRONG 0x01
+ #define ASUS_MINI_LED_2024_OFF 0x02
+#define ASUS_POWER_CORE_MASK GENMASK(15, 8)
+#define ASUS_PERF_CORE_MASK GENMASK(7, 0)
@@ -38,11 +39,14 @@ index 10764c04232a..a445bd6f57a4 100644
+ CPU_CORE_MAX,
+ CPU_CORE_CURRENT,
+};
++
++#define CPU_PERF_CORE_COUNT_MIN 4
++#define CPU_POWR_CORE_COUNT_MIN 0
+
/* Default limits for tunables available on ASUS ROG laptops */
- #define PPT_CPU_LIMIT_MIN 5
- #define PPT_CPU_LIMIT_MAX 150
-@@ -85,6 +100,13 @@ struct rog_tunables {
+ #define NVIDIA_BOOST_MIN 5
+ #define NVIDIA_BOOST_MAX 25
+@@ -85,6 +103,13 @@ struct rog_tunables {
u32 dgpu_tgp_min;
u32 dgpu_tgp_max;
u32 dgpu_tgp;
@@ -56,31 +60,24 @@ index 10764c04232a..a445bd6f57a4 100644
};
static const struct class *fw_attr_class;
-@@ -146,6 +168,8 @@ static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
+@@ -144,6 +169,8 @@ static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
static bool asus_bios_requires_reboot(struct kobj_attribute *attr)
{
return !strcmp(attr->attr.name, "gpu_mux_mode") ||
-+ !strcmp(attr->attr.name, "cores_performance") ||
-+ !strcmp(attr->attr.name, "cores_efficiency") ||
- !strcmp(attr->attr.name, "panel_hd_mode");
++ !strcmp(attr->attr.name, "cores_performance") ||
++ !strcmp(attr->attr.name, "cores_efficiency") ||
+ !strcmp(attr->attr.name, "panel_hd_mode");
}
-@@ -574,6 +598,197 @@ static ssize_t apu_mem_possible_values_show(struct kobject *kobj,
+@@ -559,6 +586,195 @@ static ssize_t apu_mem_possible_values_show(struct kobject *kobj, struct kobj_at
}
- ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set the available system memory for the APU to use");
+ ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set available system RAM (in GB) for the APU to use");
+static int init_max_cpu_cores(void)
+{
+ u32 cores;
+ int err;
+
-+ asus_armoury.rog_tunables->min_perf_cores = 4;
-+ asus_armoury.rog_tunables->max_perf_cores = 4;
-+ asus_armoury.rog_tunables->cur_perf_cores = 4;
-+ asus_armoury.rog_tunables->min_power_cores = 0;
-+ asus_armoury.rog_tunables->max_power_cores = 8;
-+ asus_armoury.rog_tunables->cur_power_cores = 8;
-+
+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES_MAX, &cores);
+ if (err)
+ return err;
@@ -89,21 +86,23 @@ index 10764c04232a..a445bd6f57a4 100644
+ asus_armoury.rog_tunables->max_power_cores = FIELD_GET(ASUS_POWER_CORE_MASK, cores);
+ asus_armoury.rog_tunables->max_perf_cores = FIELD_GET(ASUS_PERF_CORE_MASK, cores);
+
-+ cores = 0;
+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES, &cores);
-+ if (err)
++ if (err) {
++ pr_err("Could not get CPU core count: error %d", err);
+ return err;
++ }
+
+ asus_armoury.rog_tunables->cur_perf_cores = FIELD_GET(ASUS_PERF_CORE_MASK, cores);
+ asus_armoury.rog_tunables->cur_power_cores = FIELD_GET(ASUS_POWER_CORE_MASK, cores);
+
++ asus_armoury.rog_tunables->min_perf_cores = CPU_PERF_CORE_COUNT_MIN;
++ asus_armoury.rog_tunables->min_power_cores = CPU_POWR_CORE_COUNT_MIN;
++
+ return 0;
+}
+
-+static ssize_t cores_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf,
-+ enum cpu_core_type core_type,
-+ enum cpu_core_value core_value)
++static ssize_t cores_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf,
++ enum cpu_core_type core_type, enum cpu_core_value core_value)
+{
+ u32 cores;
+
@@ -111,14 +110,18 @@ index 10764c04232a..a445bd6f57a4 100644
+ case CPU_CORE_DEFAULT:
+ case CPU_CORE_MAX:
+ if (core_type == CPU_CORE_PERF)
-+ return sysfs_emit(buf, "%d\n", asus_armoury.rog_tunables->max_perf_cores);
++ return sysfs_emit(buf, "%d\n",
++ asus_armoury.rog_tunables->max_perf_cores);
+ else
-+ return sysfs_emit(buf, "%d\n", asus_armoury.rog_tunables->max_power_cores);
++ return sysfs_emit(buf, "%d\n",
++ asus_armoury.rog_tunables->max_power_cores);
+ case CPU_CORE_MIN:
+ if (core_type == CPU_CORE_PERF)
-+ return sysfs_emit(buf, "%d\n", asus_armoury.rog_tunables->min_perf_cores);
++ return sysfs_emit(buf, "%d\n",
++ asus_armoury.rog_tunables->min_perf_cores);
+ else
-+ return sysfs_emit(buf, "%d\n", asus_armoury.rog_tunables->min_power_cores);
++ return sysfs_emit(buf, "%d\n",
++ asus_armoury.rog_tunables->min_power_cores);
+ default:
+ break;
+ }
@@ -131,12 +134,11 @@ index 10764c04232a..a445bd6f57a4 100644
+ return sysfs_emit(buf, "%d\n", cores);
+}
+
-+static ssize_t cores_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr, const char *buf,
-+ enum cpu_core_type core_type)
++static ssize_t cores_current_value_store(struct kobject *kobj, struct kobj_attribute *attr,
++ const char *buf, enum cpu_core_type core_type)
+{
++ u32 new_cores, perf_cores, power_cores, out_val, min, max;
+ int result, err;
-+ u32 new_cores, perf_cores, powr_cores, out_val, min, max;
+
+ result = kstrtou32(buf, 10, &new_cores);
+ if (result)
@@ -144,12 +146,12 @@ index 10764c04232a..a445bd6f57a4 100644
+
+ if (core_type == CPU_CORE_PERF) {
+ perf_cores = new_cores;
-+ powr_cores = out_val = asus_armoury.rog_tunables->cur_power_cores;
++ power_cores = out_val = asus_armoury.rog_tunables->cur_power_cores;
+ min = asus_armoury.rog_tunables->min_perf_cores;
+ max = asus_armoury.rog_tunables->max_perf_cores;
+ } else {
+ perf_cores = asus_armoury.rog_tunables->cur_perf_cores;
-+ powr_cores = out_val = new_cores;
++ power_cores = out_val = new_cores;
+ min = asus_armoury.rog_tunables->min_power_cores;
+ max = asus_armoury.rog_tunables->max_power_cores;
+ }
@@ -159,7 +161,7 @@ index 10764c04232a..a445bd6f57a4 100644
+
+ out_val = 0;
+ out_val |= FIELD_PREP(ASUS_PERF_CORE_MASK, perf_cores);
-+ out_val |= FIELD_PREP(ASUS_POWER_CORE_MASK, powr_cores);
++ out_val |= FIELD_PREP(ASUS_POWER_CORE_MASK, power_cores);
+
+ mutex_lock(&asus_armoury.mutex);
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_CORES, out_val, &result);
@@ -183,32 +185,32 @@ index 10764c04232a..a445bd6f57a4 100644
+}
+
+static ssize_t cores_performance_min_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++ struct kobj_attribute *attr, char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MIN);
+}
+
+static ssize_t cores_performance_max_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++ struct kobj_attribute *attr, char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MAX);
+}
+
+static ssize_t cores_performance_default_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++ struct kobj_attribute *attr, char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_DEFAULT);
+}
+
+static ssize_t cores_performance_current_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++ struct kobj_attribute *attr, char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_CURRENT);
+}
+
+static ssize_t cores_performance_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
++ struct kobj_attribute *attr,
++ const char *buf, size_t count)
+{
+ int err;
+
@@ -219,35 +221,35 @@ index 10764c04232a..a445bd6f57a4 100644
+ return count;
+}
+ATTR_GROUP_CORES_RW(cores_performance, "cores_performance",
-+ "Set the max available performance cores");
++ "Set the max available performance cores");
+
-+static ssize_t cores_efficiency_min_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++static ssize_t cores_efficiency_min_value_show(struct kobject *kobj, struct kobj_attribute *attr,
++ char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MIN);
+}
+
-+static ssize_t cores_efficiency_max_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++static ssize_t cores_efficiency_max_value_show(struct kobject *kobj, struct kobj_attribute *attr,
++ char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MAX);
+}
+
+static ssize_t cores_efficiency_default_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++ struct kobj_attribute *attr, char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_DEFAULT);
+}
+
+static ssize_t cores_efficiency_current_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
++ struct kobj_attribute *attr, char *buf)
+{
+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_CURRENT);
+}
+
+static ssize_t cores_efficiency_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
++ struct kobj_attribute *attr, const char *buf,
++ size_t count)
+{
+ int err;
+
@@ -258,12 +260,12 @@ index 10764c04232a..a445bd6f57a4 100644
+ return count;
+}
+ATTR_GROUP_CORES_RW(cores_efficiency, "cores_efficiency",
-+ "Set the max available efficiency cores");
++ "Set the max available efficiency cores");
+
/* Simple attribute creation */
- ATTR_GROUP_ROG_TUNABLE(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL,
- cpu_default, cpu_min, cpu_max, 1, "Set the CPU slow package limit");
-@@ -625,6 +840,8 @@ static const struct asus_attr_group armoury_attr_groups[] = {
+ ATTR_GROUP_ROG_TUNABLE(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL, cpu_default,
+ cpu_min, cpu_max, 1, "Set the CPU slow package limit");
+@@ -615,6 +831,8 @@ static const struct asus_attr_group armoury_attr_groups[] = {
{ &dgpu_base_tgp_attr_group, ASUS_WMI_DEVID_DGPU_BASE_TGP },
{ &dgpu_tgp_attr_group, ASUS_WMI_DEVID_DGPU_SET_TGP },
{ &apu_mem_attr_group, ASUS_WMI_DEVID_APU_MEM },
@@ -272,59 +274,65 @@ index 10764c04232a..a445bd6f57a4 100644
{ &charge_mode_attr_group, ASUS_WMI_DEVID_CHARGE_MODE },
{ &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND },
-@@ -812,6 +1029,7 @@ static int __init asus_fw_init(void)
+@@ -817,6 +1035,14 @@ static int __init asus_fw_init(void)
return -ENOMEM;
- }
+
init_rog_tunables(asus_armoury.rog_tunables);
-+ init_max_cpu_cores();
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_CORES_MAX)) {
++ err = init_max_cpu_cores();
++ if (err) {
++ kfree(asus_armoury.rog_tunables);
++ pr_err("Could not initialise CPU core control %d\n", err);
++ return err;
++ }
++ }
err = asus_fw_attr_add();
if (err)
diff --git a/drivers/platform/x86/asus-armoury.h b/drivers/platform/x86/asus-armoury.h
-index 1652c44c3c9f..78c9278b2e75 100644
+index 9639e7ca772f..2620708d3994 100644
--- a/drivers/platform/x86/asus-armoury.h
+++ b/drivers/platform/x86/asus-armoury.h
-@@ -169,6 +169,35 @@ static const struct attribute_group _attrname##_attr_group = { \
- .attrs = _attrname##_attrs \
- }
+@@ -168,6 +168,34 @@ static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr,
+ .name = _fsname, .attrs = _attrname##_attrs \
+ }
+/* CPU core attributes need a little different in setup */
-+#define ATTR_GROUP_CORES_RW(_attrname, _fsname, _dispname) \
-+__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", 1); \
-+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-+static struct kobj_attribute attr_##_attrname##_current_value = \
-+ __ASUS_ATTR_RW(_attrname, current_value); \
-+static struct kobj_attribute attr_##_attrname##_default_value = \
-+ __ASUS_ATTR_RO(_attrname, default_value); \
-+static struct kobj_attribute attr_##_attrname##_min_value = \
-+ __ASUS_ATTR_RO(_attrname, min_value); \
-+static struct kobj_attribute attr_##_attrname##_max_value = \
-+ __ASUS_ATTR_RO(_attrname, max_value); \
-+static struct kobj_attribute attr_##_attrname##_type = \
-+ __ASUS_ATTR_RO_AS(type, int_type_show); \
-+static struct attribute *_attrname##_attrs[] = { \
-+ &attr_##_attrname##_current_value.attr, \
-+ &attr_##_attrname##_default_value.attr, \
-+ &attr_##_attrname##_min_value.attr, \
-+ &attr_##_attrname##_max_value.attr, \
-+ &attr_##_attrname##_scalar_increment.attr, \
-+ &attr_##_attrname##_display_name.attr, \
-+ &attr_##_attrname##_type.attr, \
-+ NULL \
-+}; \
-+static const struct attribute_group _attrname##_attr_group = { \
-+ .name = _fsname, \
-+ .attrs = _attrname##_attrs \
-+}
++#define ATTR_GROUP_CORES_RW(_attrname, _fsname, _dispname) \
++ __ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", 1); \
++ __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
++ static struct kobj_attribute attr_##_attrname##_current_value = \
++ __ASUS_ATTR_RW(_attrname, current_value); \
++ static struct kobj_attribute attr_##_attrname##_default_value = \
++ __ASUS_ATTR_RO(_attrname, default_value); \
++ static struct kobj_attribute attr_##_attrname##_min_value = \
++ __ASUS_ATTR_RO(_attrname, min_value); \
++ static struct kobj_attribute attr_##_attrname##_max_value = \
++ __ASUS_ATTR_RO(_attrname, max_value); \
++ static struct kobj_attribute attr_##_attrname##_type = \
++ __ASUS_ATTR_RO_AS(type, int_type_show); \
++ static struct attribute *_attrname##_attrs[] = { \
++ &attr_##_attrname##_current_value.attr, \
++ &attr_##_attrname##_default_value.attr, \
++ &attr_##_attrname##_min_value.attr, \
++ &attr_##_attrname##_max_value.attr, \
++ &attr_##_attrname##_scalar_increment.attr, \
++ &attr_##_attrname##_display_name.attr, \
++ &attr_##_attrname##_type.attr, \
++ NULL \
++ }; \
++ static const struct attribute_group _attrname##_attr_group = { \
++ .name = _fsname, .attrs = _attrname##_attrs \
++ }
+
/*
* ROG PPT attributes need a little different in setup as they
* require rog_tunables members.
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index e1aeafdf05d5..8964e601543a 100644
+index 88bf250dc8ca..cc21e4272460 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -134,6 +134,10 @@
+@@ -137,6 +137,10 @@
/* dgpu on/off */
#define ASUS_WMI_DEVID_DGPU 0x00090020
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0011-platform-x86-asus-armoury-move-existing-tunings-to-a.patch b/packages/l/linux-current/files/patches/hardware/asus/0011-platform-x86-asus-armoury-move-existing-tunings-to-a.patch
deleted file mode 100644
index 51530026479..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0011-platform-x86-asus-armoury-move-existing-tunings-to-a.patch
+++ /dev/null
@@ -1,1155 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones"
-Date: Thu, 30 May 2024 13:20:11 +1200
-Subject: [PATCH 11/18] platform/x86: asus-armoury: move existing tunings to
- asus-armoury module
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The fw_attributes_class provides a much cleaner interface to all of the
-attributes introduced to asus-wmi. This patch moves all of these extra
-attributes over to fw_attributes_class, and shifts the bulk of these
-definitions to a new kernel module to reduce the clutter of asus-wmi
-with the intention of deprecating the asus-wmi attributes in future.
-
-The work applies only to WMI methods which don't have a clearly defined
-place within the sysfs and as a result ended up lumped together in
-/sys/devices/platform/asus-nb-wmi/ with no standard API.
-
-Where possible the fw attrs now implement defaults, min, max, scalar,
-choices, etc. As en example dgpu_disable becomes:
-
-/sys/class/firmware-attributes/asus-armoury/attributes/dgpu_disable/
-├── current_value
-├── display_name
-├── possible_values
-└── type
-
-as do other attributes.
-
-Signed-off-by: Luke D. Jones
----
- drivers/platform/x86/Kconfig | 14 +
- drivers/platform/x86/Makefile | 1 +
- drivers/platform/x86/asus-armoury.c | 706 +++++++++++++++++++++
- drivers/platform/x86/asus-armoury.h | 209 ++++++
- drivers/platform/x86/asus-wmi.c | 65 +-
- drivers/platform/x86/asus-wmi.h | 14 +
- include/linux/platform_data/x86/asus-wmi.h | 11 +
- 7 files changed, 1004 insertions(+), 16 deletions(-)
- create mode 100644 drivers/platform/x86/asus-armoury.c
- create mode 100644 drivers/platform/x86/asus-armoury.h
-
-diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index ddfccc226751..d13c4085c228 100644
---- a/drivers/platform/x86/Kconfig
-+++ b/drivers/platform/x86/Kconfig
-@@ -265,6 +265,19 @@ config ASUS_WIRELESS
- If you choose to compile this driver as a module the module will be
- called asus-wireless.
-
-+config ASUS_ARMOURY
-+ tristate "ASUS Armoury (firmware) Driver"
-+ depends on ACPI_WMI
-+ depends on ASUS_WMI
-+ select FW_ATTR_CLASS
-+ help
-+ Say Y here if you have a WMI aware Asus laptop and would like to use the
-+ firmware_attributes API to control various settings typically exposed in
-+ the ASUS Armoury Crate application available on Windows.
-+
-+ To compile this driver as a module, choose M here: the module will
-+ be called asus-armoury.
-+
- config ASUS_WMI
- tristate "ASUS WMI Driver"
- depends on ACPI_WMI
-@@ -276,6 +289,7 @@ config ASUS_WMI
- depends on HOTPLUG_PCI
- depends on ACPI_VIDEO || ACPI_VIDEO = n
- depends on SERIO_I8042 || SERIO_I8042 = n
-+ select ASUS_ARMOURY
- select INPUT_SPARSEKMAP
- select LEDS_CLASS
- select NEW_LEDS
-diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
-index e1b142947067..fe3e7e7dede8 100644
---- a/drivers/platform/x86/Makefile
-+++ b/drivers/platform/x86/Makefile
-@@ -32,6 +32,7 @@ obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
- # ASUS
- obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
- obj-$(CONFIG_ASUS_WIRELESS) += asus-wireless.o
-+obj-$(CONFIG_ASUS_ARMOURY) += asus-armoury.o
- obj-$(CONFIG_ASUS_WMI) += asus-wmi.o
- obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o
- obj-$(CONFIG_ASUS_TF103C_DOCK) += asus-tf103c-dock.o
-diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
-new file mode 100644
-index 000000000000..0bbc85170ade
---- /dev/null
-+++ b/drivers/platform/x86/asus-armoury.c
-@@ -0,0 +1,706 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Asus Armoury (WMI) attributes driver. This driver uses the fw_attributes
-+ * class to expose the various WMI functions that many gaming and some
-+ * non-gaming ASUS laptops have available.
-+ * These typically don't fit anywhere else in the sysfs such as under LED class,
-+ * hwmon or other, and are set in Windows using the ASUS Armoury Crate tool.
-+ *
-+ * Copyright(C) 2010 Intel Corporation.
-+ * Copyright(C) 2024-2024 Luke Jones
-+ */
-+
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+ #include
-+
-+#include "asus-armoury.h"
-+#include "firmware_attributes_class.h"
-+#include "asus-wmi.h"
-+
-+#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C"
-+
-+#define ASUS_MINI_LED_MODE_MASK 0x03
-+/* Standard modes for devices with only on/off */
-+#define ASUS_MINI_LED_OFF 0x00
-+#define ASUS_MINI_LED_ON 0x01
-+/* New mode on some devices, define here to clarify remapping later */
-+#define ASUS_MINI_LED_STRONG_MODE 0x02
-+/* New modes for devices with 3 mini-led mode types */
-+#define ASUS_MINI_LED_2024_WEAK 0x00
-+#define ASUS_MINI_LED_2024_STRONG 0x01
-+#define ASUS_MINI_LED_2024_OFF 0x02
-+
-+/* Default limits for tunables available on ASUS ROG laptops */
-+#define PPT_CPU_LIMIT_MIN 5
-+#define PPT_CPU_LIMIT_MAX 150
-+#define PPT_CPU_LIMIT_DEFAULT 80
-+#define PPT_PLATFORM_MIN 5
-+#define PPT_PLATFORM_MAX 100
-+#define PPT_PLATFORM_DEFAULT 80
-+#define NVIDIA_BOOST_MIN 5
-+#define NVIDIA_BOOST_MAX 25
-+#define NVIDIA_TEMP_MIN 75
-+#define NVIDIA_TEMP_MAX 87
-+
-+/* Tunables provided by ASUS for gaming laptops */
-+struct rog_tunables {
-+ u32 cpu_default;
-+ u32 cpu_min;
-+ u32 cpu_max;
-+
-+ u32 platform_default;
-+ u32 platform_min;
-+ u32 platform_max;
-+
-+ u32 ppt_pl1_spl; // cpu
-+ u32 ppt_pl2_sppt; // cpu
-+ u32 ppt_apu_sppt; // plat
-+ u32 ppt_platform_sppt; // plat
-+ u32 ppt_fppt; // cpu
-+
-+ u32 nv_boost_default;
-+ u32 nv_boost_min;
-+ u32 nv_boost_max;
-+ u32 nv_dynamic_boost;
-+
-+ u32 nv_temp_default;
-+ u32 nv_temp_min;
-+ u32 nv_temp_max;
-+ u32 nv_temp_target;
-+};
-+
-+static const struct class *fw_attr_class;
-+
-+struct asus_armoury_priv {
-+ struct device *fw_attr_dev;
-+ struct kset *fw_attr_kset;
-+
-+ struct rog_tunables *rog_tunables;
-+ u32 mini_led_dev_id;
-+ u32 gpu_mux_dev_id;
-+
-+ struct mutex mutex;
-+};
-+
-+static struct asus_armoury_priv asus_armoury = {
-+ .mutex = __MUTEX_INITIALIZER(asus_armoury.mutex)
-+};
-+
-+struct fw_attrs_group {
-+ bool pending_reboot;
-+};
-+
-+static struct fw_attrs_group fw_attrs = {
-+ .pending_reboot = false,
-+};
-+
-+struct asus_attr_group {
-+ const struct attribute_group *attr_group;
-+ u32 wmi_devid;
-+};
-+
-+static bool asus_wmi_is_present(u32 dev_id)
-+{
-+ u32 retval;
-+ int status;
-+
-+ status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0, &retval);
-+ pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval);
-+
-+ return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
-+}
-+
-+static void asus_set_reboot_and_signal_event(void)
-+{
-+ fw_attrs.pending_reboot = true;
-+ kobject_uevent(&asus_armoury.fw_attr_dev->kobj, KOBJ_CHANGE);
-+}
-+
-+static ssize_t pending_reboot_show(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ char *buf)
-+{
-+ return sysfs_emit(buf, "%d\n", fw_attrs.pending_reboot);
-+}
-+
-+static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
-+
-+static bool asus_bios_requires_reboot(struct kobj_attribute *attr)
-+{
-+ return !strcmp(attr->attr.name, "gpu_mux_mode") ||
-+ !strcmp(attr->attr.name, "panel_hd_mode");
-+}
-+
-+/**
-+ * attr_int_store() - Generic store function for use with most WMI functions.
-+ * @kobj: Pointer to the driver object.
-+ * @kobj_attribute: Pointer the the attribute calling this function.
-+ * @buf: The buffer to read from, this is parsed to `int` type.
-+ * @count:
-+ * @min: Minimum accepted value. Below this returns -EINVAL.
-+ * @max: Maximum accepted value. Above this returns -EINVAL.
-+ * @store_value: Pointer to where the parsed value should be stored.
-+ * @wmi_dev: The WMI function ID to use.
-+ *
-+ * The WMI functions available on most ASUS laptops return a 1 as "success", and
-+ * a 0 as failed. However some functions can return n > 1 for additional errors.
-+ * attr_int_store() currently treats all values which are not 1 as errors, ignoring
-+ * the possible differences in WMI error returns.
-+ *
-+ * Returns: Either count, or an error.
-+ */
-+static ssize_t attr_int_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count,
-+ u32 min, u32 max, u32 *store_value, u32 wmi_dev)
-+{
-+ u32 result, value;
-+ int err;
-+
-+ err = kstrtouint(buf, 10, &value);
-+ if (err)
-+ return err;
-+
-+ if (value < min || value > max)
-+ return -EINVAL;
-+
-+ err = asus_wmi_set_devstate(wmi_dev, value, &result);
-+ if (err) {
-+ pr_err("Failed to set %s: %d\n", attr->attr.name, err);
-+ return err;
-+ }
-+
-+ if (result != 1) {
-+ pr_err("Failed to set %s (result): 0x%x\n", attr->attr.name, result);
-+ return -EIO;
-+ }
-+
-+ if (store_value != NULL)
-+ *store_value = value;
-+ sysfs_notify(kobj, NULL, attr->attr.name);
-+
-+ if (asus_bios_requires_reboot(attr))
-+ asus_set_reboot_and_signal_event();
-+
-+ return count;
-+}
-+
-+/* Mini-LED mode **************************************************************/
-+static ssize_t mini_led_mode_current_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ u32 value;
-+ int err;
-+
-+ err = asus_wmi_get_devstate_dsts(asus_armoury.mini_led_dev_id, &value);
-+ if (err)
-+ return err;
-+
-+ value &= ASUS_MINI_LED_MODE_MASK;
-+
-+ /*
-+ * Remap the mode values to match previous generation mini-LED. The last gen
-+ * WMI 0 == off, while on this version WMI 2 == off (flipped).
-+ */
-+ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
-+ switch (value) {
-+ case ASUS_MINI_LED_2024_WEAK:
-+ value = ASUS_MINI_LED_ON;
-+ break;
-+ case ASUS_MINI_LED_2024_STRONG:
-+ value = ASUS_MINI_LED_STRONG_MODE;
-+ break;
-+ case ASUS_MINI_LED_2024_OFF:
-+ value = ASUS_MINI_LED_OFF;
-+ break;
-+ }
-+ }
-+
-+ return sysfs_emit(buf, "%u\n", value);
-+}
-+
-+static ssize_t mini_led_mode_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int result, err;
-+ u32 mode;
-+
-+ err = kstrtou32(buf, 10, &mode);
-+ if (err)
-+ return err;
-+
-+ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE &&
-+ mode > ASUS_MINI_LED_ON)
-+ return -EINVAL;
-+ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 &&
-+ mode > ASUS_MINI_LED_STRONG_MODE)
-+ return -EINVAL;
-+
-+ /*
-+ * Remap the mode values so expected behaviour is the same as the last
-+ * generation of mini-LED with 0 == off, 1 == on.
-+ */
-+ if (asus_armoury.mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
-+ switch (mode) {
-+ case ASUS_MINI_LED_OFF:
-+ mode = ASUS_MINI_LED_2024_OFF;
-+ break;
-+ case ASUS_MINI_LED_ON:
-+ mode = ASUS_MINI_LED_2024_WEAK;
-+ break;
-+ case ASUS_MINI_LED_STRONG_MODE:
-+ mode = ASUS_MINI_LED_2024_STRONG;
-+ break;
-+ }
-+ }
-+
-+ err = asus_wmi_set_devstate(asus_armoury.mini_led_dev_id, mode, &result);
-+ if (err) {
-+ pr_warn("Failed to set mini-LED: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result != 1) {
-+ pr_warn("Failed to set mini-LED mode (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(kobj, NULL, attr->attr.name);
-+
-+ return count;
-+}
-+
-+static ssize_t mini_led_mode_possible_values_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ switch (asus_armoury.mini_led_dev_id) {
-+ case ASUS_WMI_DEVID_MINI_LED_MODE:
-+ return sysfs_emit(buf, "0;1\n");
-+ case ASUS_WMI_DEVID_MINI_LED_MODE2:
-+ return sysfs_emit(buf, "0;1;2\n");
-+ }
-+
-+ return sysfs_emit(buf, "0\n");
-+}
-+
-+ATTR_GROUP_ENUM_CUSTOM(mini_led_mode, "mini_led_mode", "Set the mini-LED backlight mode");
-+
-+static ssize_t gpu_mux_mode_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int result, err;
-+ u32 optimus;
-+
-+ err = kstrtou32(buf, 10, &optimus);
-+ if (err)
-+ return err;
-+
-+ if (optimus > 1)
-+ return -EINVAL;
-+
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU)) {
-+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_DGPU, &result);
-+ if (err)
-+ return err;
-+ if (result && !optimus) {
-+ err = -ENODEV;
-+ pr_warn("Can not switch MUX to dGPU mode when dGPU is disabled: %02X %02X %d\n", result, optimus, err);
-+ return err;
-+ }
-+ }
-+
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_EGPU)) {
-+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_EGPU, &result);
-+ if (err)
-+ return err;
-+ if (result && !optimus) {
-+ err = -ENODEV;
-+ pr_warn("Can not switch MUX to dGPU mode when eGPU is enabled: %d\n", err);
-+ return err;
-+ }
-+ }
-+
-+ err = asus_wmi_set_devstate(asus_armoury.gpu_mux_dev_id, optimus, &result);
-+ if (err) {
-+ pr_err("Failed to set GPU MUX mode: %d\n", err);
-+ return err;
-+ }
-+ /* !1 is considered a fail by ASUS */
-+ if (result != 1) {
-+ pr_warn("Failed to set GPU MUX mode (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(kobj, NULL, attr->attr.name);
-+ asus_set_reboot_and_signal_event();
-+
-+ return count;
-+}
-+WMI_SHOW_INT(gpu_mux_mode_current_value, "%d\n", asus_armoury.gpu_mux_dev_id);
-+ATTR_GROUP_BOOL_CUSTOM(gpu_mux_mode, "gpu_mux_mode", "Set the GPU display MUX mode");
-+
-+/*
-+ * A user may be required to store the value twice, typical store first, then
-+ * rescan PCI bus to activate power, then store a second time to save correctly.
-+ * The reason for this is that an extra code path in the ACPI is enabled when
-+ * the device and bus are powered.
-+ */
-+static ssize_t dgpu_disable_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int result, err;
-+ u32 disable;
-+
-+ err = kstrtou32(buf, 10, &disable);
-+ if (err)
-+ return err;
-+
-+ if (disable > 1)
-+ return -EINVAL;
-+
-+ if (asus_armoury.gpu_mux_dev_id) {
-+ err = asus_wmi_get_devstate_dsts(asus_armoury.gpu_mux_dev_id, &result);
-+ if (err)
-+ return err;
-+ if (!result && disable) {
-+ err = -ENODEV;
-+ pr_warn("Can not disable dGPU when the MUX is in dGPU mode: %d\n", err);
-+ return err;
-+ }
-+ }
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, disable, &result);
-+ if (err) {
-+ pr_warn("Failed to set dGPU disable: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result != 1) {
-+ pr_warn("Failed to set dGPU disable (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(kobj, NULL, attr->attr.name);
-+
-+ return count;
-+}
-+WMI_SHOW_INT(dgpu_disable_current_value, "%d\n", ASUS_WMI_DEVID_DGPU);
-+ATTR_GROUP_BOOL_CUSTOM(dgpu_disable, "dgpu_disable", "Disable the dGPU");
-+
-+/* The ACPI call to enable the eGPU also disables the internal dGPU */
-+static ssize_t egpu_enable_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int result, err;
-+ u32 enable;
-+
-+ err = kstrtou32(buf, 10, &enable);
-+ if (err)
-+ return err;
-+
-+ if (enable > 1)
-+ return -EINVAL;
-+
-+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_EGPU_CONNECTED, &result);
-+ if (err) {
-+ pr_warn("Failed to get eGPU connection status: %d\n", err);
-+ return err;
-+ }
-+
-+ if (asus_armoury.gpu_mux_dev_id) {
-+ err = asus_wmi_get_devstate_dsts(asus_armoury.gpu_mux_dev_id, &result);
-+ if (err) {
-+ pr_warn("Failed to get GPU MUX status: %d\n", result);
-+ return result;
-+ }
-+ if (!result && enable) {
-+ err = -ENODEV;
-+ pr_warn("Can not enable eGPU when the MUX is in dGPU mode: %d\n", err);
-+ return err;
-+ }
-+ }
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, enable, &result);
-+ if (err) {
-+ pr_warn("Failed to set eGPU state: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result != 1) {
-+ pr_warn("Failed to set eGPU state (retval): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(kobj, NULL, attr->attr.name);
-+
-+ return count;
-+}
-+WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU);
-+ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)");
-+
-+/* Simple attribute creation */
-+ATTR_GROUP_ROG_TUNABLE(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL,
-+ cpu_default, cpu_min, cpu_max, 1, "Set the CPU slow package limit");
-+ATTR_GROUP_ROG_TUNABLE(ppt_pl2_sppt, "ppt_pl2_sppt", ASUS_WMI_DEVID_PPT_PL2_SPPT,
-+ cpu_default, cpu_min, cpu_max, 1, "Set the CPU fast package limit");
-+ATTR_GROUP_ROG_TUNABLE(ppt_apu_sppt, "ppt_apu_sppt", ASUS_WMI_DEVID_PPT_APU_SPPT,
-+ platform_default, platform_min, platform_max, 1, "Set the CPU slow package limit");
-+ATTR_GROUP_ROG_TUNABLE(ppt_platform_sppt, "ppt_platform_sppt", ASUS_WMI_DEVID_PPT_PLAT_SPPT,
-+ platform_default, platform_min, platform_max, 1, "Set the CPU slow package limit");
-+ATTR_GROUP_ROG_TUNABLE(ppt_fppt, "ppt_fppt", ASUS_WMI_DEVID_PPT_FPPT,
-+ cpu_default, cpu_min, cpu_max, 1, "Set the CPU slow package limit");
-+
-+ATTR_GROUP_ROG_TUNABLE(nv_dynamic_boost, "nv_dynamic_boost", ASUS_WMI_DEVID_NV_DYN_BOOST,
-+ nv_boost_default, nv_boost_min, nv_boost_max, 1, "Set the Nvidia dynamic boost limit");
-+ATTR_GROUP_ROG_TUNABLE(nv_temp_target, "nv_temp_target", ASUS_WMI_DEVID_NV_THERM_TARGET,
-+ nv_temp_default, nv_boost_min, nv_temp_max, 1, "Set the Nvidia max thermal limit");
-+
-+ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE,
-+ "0;1;2", "Show the current mode of charging");
-+ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND,
-+ "Set the boot POST sound");
-+ATTR_GROUP_BOOL_RW(mcu_powersave, "mcu_powersave", ASUS_WMI_DEVID_MCU_POWERSAVE,
-+ "Set MCU powersaving mode");
-+ATTR_GROUP_BOOL_RW(panel_od, "panel_overdrive", ASUS_WMI_DEVID_PANEL_OD,
-+ "Set the panel refresh overdrive");
-+ATTR_GROUP_BOOL_RW(panel_hd_mode, "panel_hd_mode", ASUS_WMI_DEVID_PANEL_HD,
-+ "Set the panel HD mode to UHD<0> or FHD<1>");
-+ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED,
-+ "Show the eGPU connection status");
-+
-+/* If an attribute does not require any special case handling add it here */
-+static const struct asus_attr_group armoury_attr_groups[] = {
-+ { &egpu_connected_attr_group, ASUS_WMI_DEVID_EGPU_CONNECTED },
-+ { &egpu_enable_attr_group, ASUS_WMI_DEVID_EGPU },
-+ { &dgpu_disable_attr_group, ASUS_WMI_DEVID_DGPU },
-+
-+ { &ppt_pl1_spl_attr_group, ASUS_WMI_DEVID_PPT_PL1_SPL },
-+ { &ppt_pl2_sppt_attr_group, ASUS_WMI_DEVID_PPT_PL2_SPPT },
-+ { &ppt_apu_sppt_attr_group, ASUS_WMI_DEVID_PPT_APU_SPPT },
-+ { &ppt_platform_sppt_attr_group, ASUS_WMI_DEVID_PPT_PLAT_SPPT },
-+ { &ppt_fppt_attr_group, ASUS_WMI_DEVID_PPT_FPPT },
-+ { &nv_dynamic_boost_attr_group, ASUS_WMI_DEVID_NV_DYN_BOOST },
-+ { &nv_temp_target_attr_group, ASUS_WMI_DEVID_NV_THERM_TARGET },
-+
-+ { &charge_mode_attr_group, ASUS_WMI_DEVID_CHARGE_MODE },
-+ { &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND },
-+ { &mcu_powersave_attr_group, ASUS_WMI_DEVID_MCU_POWERSAVE },
-+ { &panel_od_attr_group, ASUS_WMI_DEVID_PANEL_OD },
-+ { &panel_hd_mode_attr_group, ASUS_WMI_DEVID_PANEL_HD },
-+};
-+
-+static int asus_fw_attr_add(void)
-+{
-+ int err;
-+
-+ err = fw_attributes_class_get(&fw_attr_class);
-+ if (err)
-+ goto fail_class_created;
-+
-+ asus_armoury.fw_attr_dev = device_create(fw_attr_class, NULL,
-+ MKDEV(0, 0), NULL, "%s", DRIVER_NAME);
-+
-+ if (IS_ERR(asus_armoury.fw_attr_dev)) {
-+ err = PTR_ERR(asus_armoury.fw_attr_dev);
-+ goto fail_class_created;
-+ }
-+
-+ asus_armoury.fw_attr_kset = kset_create_and_add("attributes", NULL,
-+ &asus_armoury.fw_attr_dev->kobj);
-+ if (!asus_armoury.fw_attr_dev) {
-+ err = -ENOMEM;
-+ pr_debug("Failed to create and add attributes\n");
-+ goto err_destroy_classdev;
-+ }
-+
-+ err = sysfs_create_file(&asus_armoury.fw_attr_kset->kobj, &pending_reboot.attr);
-+ if (err) {
-+ pr_warn("Failed to create sysfs level attributes\n");
-+ goto fail_class_created;
-+ }
-+
-+ err = 0;
-+ asus_armoury.mini_led_dev_id = 0;
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_MINI_LED_MODE)) {
-+ asus_armoury.mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;
-+ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj,
-+ &mini_led_mode_attr_group);
-+ } else if (asus_wmi_is_present(ASUS_WMI_DEVID_MINI_LED_MODE2)) {
-+ asus_armoury.mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2;
-+ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj,
-+ &mini_led_mode_attr_group);
-+ }
-+ if (err)
-+ pr_warn("Failed to create sysfs-group for mini_led\n");
-+
-+ err = 0;
-+ asus_armoury.gpu_mux_dev_id = 0;
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_GPU_MUX)) {
-+ asus_armoury.gpu_mux_dev_id = ASUS_WMI_DEVID_GPU_MUX;
-+ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &gpu_mux_mode_attr_group);
-+ } else if (asus_wmi_is_present(ASUS_WMI_DEVID_GPU_MUX_VIVO)) {
-+ asus_armoury.gpu_mux_dev_id = ASUS_WMI_DEVID_GPU_MUX_VIVO;
-+ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &gpu_mux_mode_attr_group);
-+ }
-+ if (err)
-+ pr_warn("Failed to create sysfs-group for gpu_mux\n");
-+
-+ for (int i = 0; i < ARRAY_SIZE(armoury_attr_groups); i++) {
-+ /* Do not show for the Ally devices as powersave is entirely unreliable on it */
-+ if (armoury_attr_groups[i].wmi_devid == ASUS_WMI_DEVID_MCU_POWERSAVE &&
-+ dmi_check_system(asus_rog_ally_device))
-+ continue;
-+
-+ if (!asus_wmi_is_present(armoury_attr_groups[i].wmi_devid))
-+ continue;
-+
-+ err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj,
-+ armoury_attr_groups[i].attr_group);
-+ if (err)
-+ pr_warn("Failed to create sysfs-group for %s\n",
-+ armoury_attr_groups[i].attr_group->name);
-+ else
-+ pr_debug("Created sysfs-group for %s\n",
-+ armoury_attr_groups[i].attr_group->name);
-+ }
-+
-+ return 0;
-+
-+err_destroy_classdev:
-+ device_destroy(fw_attr_class, MKDEV(0, 0));
-+
-+fail_class_created:
-+ fw_attributes_class_put();
-+ return err;
-+}
-+
-+/* Init / exit ****************************************************************/
-+
-+/* Set up the min/max and defaults for ROG tunables */
-+static void init_rog_tunables(struct rog_tunables *rog)
-+{
-+ const char *product;
-+ u32 max_boost = NVIDIA_BOOST_MAX;
-+ u32 cpu_default = PPT_CPU_LIMIT_DEFAULT;
-+ u32 cpu_max = PPT_CPU_LIMIT_MAX;
-+ u32 platform_default = PPT_PLATFORM_DEFAULT;
-+ u32 platform_max = PPT_PLATFORM_MAX;
-+
-+ /*
-+ * ASUS product_name contains everything required, e.g,
-+ * "ROG Flow X16 GV601VV_GV601VV_00185149B"
-+ */
-+ product = dmi_get_system_info(DMI_PRODUCT_NAME);
-+
-+ if (strstr(product, "GA402R")) {
-+ cpu_default = 125;
-+ } else if (strstr(product, "13QY")) {
-+ cpu_max = 250;
-+ } else if (strstr(product, "X13")) {
-+ cpu_max = 75;
-+ cpu_default = 50;
-+ } else if (strstr(product, "RC71")
-+ || strstr(product, "RC72")) {
-+ cpu_max = 50;
-+ cpu_default = 30;
-+ } else if (strstr(product, "G814")
-+ || strstr(product, "G614")
-+ || strstr(product, "G834")
-+ || strstr(product, "G634")) {
-+ cpu_max = 175;
-+ } else if (strstr(product, "GA402X")
-+ || strstr(product, "GA403")
-+ || strstr(product, "FA507N")
-+ || strstr(product, "FA507X")
-+ || strstr(product, "FA707N")
-+ || strstr(product, "FA707X")) {
-+ cpu_max = 90;
-+ }
-+
-+ if (strstr(product, "GZ301ZE"))
-+ max_boost = 5;
-+ else if (strstr(product, "FX507ZC4"))
-+ max_boost = 15;
-+ else if (strstr(product, "GU605"))
-+ max_boost = 20;
-+
-+ /* ensure defaults for tunables */
-+ rog->cpu_default = cpu_default;
-+ rog->cpu_min = PPT_CPU_LIMIT_MIN;
-+ rog->cpu_max = cpu_max;
-+
-+ rog->platform_default = platform_default;
-+ rog->platform_max = PPT_PLATFORM_MIN;
-+ rog->platform_max = platform_max;
-+
-+ rog->ppt_pl1_spl = cpu_default;
-+ rog->ppt_pl2_sppt = cpu_default;
-+ rog->ppt_apu_sppt = cpu_default;
-+
-+ rog->ppt_platform_sppt = platform_default;
-+ rog->ppt_fppt = cpu_default;
-+
-+ rog->nv_boost_default = NVIDIA_BOOST_MAX;
-+ rog->nv_boost_max = NVIDIA_BOOST_MIN;
-+ rog->nv_boost_max = max_boost;
-+ rog->nv_dynamic_boost = NVIDIA_BOOST_MIN;
-+
-+ rog->nv_temp_default = NVIDIA_TEMP_MAX;
-+ rog->nv_temp_max = NVIDIA_TEMP_MIN;
-+ rog->nv_temp_max = NVIDIA_TEMP_MAX;
-+ rog->nv_temp_target = NVIDIA_TEMP_MIN;
-+
-+}
-+
-+static int __init asus_fw_init(void)
-+{
-+ int err;
-+
-+ fw_attrs.pending_reboot = false;
-+
-+ asus_armoury.rog_tunables = kzalloc(sizeof(struct rog_tunables), GFP_KERNEL);
-+ if (!asus_armoury.rog_tunables) {
-+ return -ENOMEM;
-+ }
-+ init_rog_tunables(asus_armoury.rog_tunables);
-+
-+ err = asus_fw_attr_add();
-+ if (err)
-+ return err;
-+
-+ return 0;
-+}
-+
-+static void __exit asus_fw_exit(void)
-+{
-+ mutex_lock(&asus_armoury.mutex);
-+
-+ sysfs_remove_file(&asus_armoury.fw_attr_kset->kobj, &pending_reboot.attr);
-+ kset_unregister(asus_armoury.fw_attr_kset);
-+ device_destroy(fw_attr_class, MKDEV(0, 0));
-+ fw_attributes_class_put();
-+
-+ mutex_unlock(&asus_armoury.mutex);
-+}
-+
-+module_init(asus_fw_init);
-+module_exit(asus_fw_exit);
-+
-+MODULE_AUTHOR("Luke Jones ");
-+MODULE_DESCRIPTION("ASUS BIOS Configuration Driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID);
-diff --git a/drivers/platform/x86/asus-armoury.h b/drivers/platform/x86/asus-armoury.h
-new file mode 100644
-index 000000000000..8a357fb6e071
---- /dev/null
-+++ b/drivers/platform/x86/asus-armoury.h
-@@ -0,0 +1,209 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Definitions for kernel modules using asus-armoury driver
-+ *
-+ * Copyright (c) 2024 Luke Jones
-+ */
-+
-+#ifndef _ASUS_BIOSCFG_H_
-+#define _ASUS_BIOSCFG_H_
-+
-+#include
-+
-+#define DRIVER_NAME "asus-armoury"
-+
-+static ssize_t attr_int_store(struct kobject *kobj, struct kobj_attribute *attr,
-+ const char *buf, size_t count,
-+ u32 min, u32 max, u32 *store_value, u32 wmi_dev);
-+
-+
-+static ssize_t int_type_show(struct kobject *kobj, struct kobj_attribute *attr,
-+ char *buf)
-+{
-+ return sysfs_emit(buf, "integer\n");
-+}
-+
-+static ssize_t enum_type_show(struct kobject *kobj, struct kobj_attribute *attr,
-+ char *buf)
-+{
-+ return sysfs_emit(buf, "enumeration\n");
-+}
-+
-+#define __ASUS_ATTR_RO(_func, _name) { \
-+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
-+ .show = _func##_##_name##_show, \
-+}
-+
-+#define __ASUS_ATTR_RO_AS(_name, _show) { \
-+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
-+ .show = _show, \
-+}
-+
-+#define __ASUS_ATTR_RW(_func, _name) __ATTR(_name, 0644, \
-+ _func##_##_name##_show, _func##_##_name##_store)
-+
-+#define __WMI_STORE_INT(_attr, _min, _max, _wmi) \
-+static ssize_t _attr##_store(struct kobject *kobj, \
-+ struct kobj_attribute *attr, \
-+ const char *buf, size_t count) \
-+{ \
-+ return attr_int_store(kobj, attr, buf, count, _min, _max, NULL, _wmi); \
-+}
-+
-+#define WMI_SHOW_INT(_attr, _fmt, _wmi) \
-+static ssize_t _attr##_show(struct kobject *kobj, \
-+ struct kobj_attribute *attr, char *buf) \
-+{ \
-+ u32 result; \
-+ int err; \
-+ err = asus_wmi_get_devstate_dsts(_wmi, &result); \
-+ if (err) \
-+ return err; \
-+ return sysfs_emit(buf, _fmt, \
-+ result & ~ASUS_WMI_DSTS_PRESENCE_BIT); \
-+}
-+
-+/* Create functions and attributes for use in other macros or on their own */
-+
-+#define __ATTR_CURRENT_INT_RO(_attr, _wmi) \
-+WMI_SHOW_INT(_attr##_current_value, "%d\n", _wmi); \
-+static struct kobj_attribute attr_##_attr##_current_value = \
-+ __ASUS_ATTR_RO(_attr, current_value)
-+
-+#define __ATTR_CURRENT_INT_RW(_attr, _minv, _maxv, _wmi) \
-+__WMI_STORE_INT(_attr##_current_value, _minv, _maxv, _wmi); \
-+WMI_SHOW_INT(_attr##_current_value, "%d\n", _wmi); \
-+static struct kobj_attribute attr_##_attr##_current_value = \
-+ __ASUS_ATTR_RW(_attr, current_value)
-+
-+/* Shows a formatted static variable */
-+#define __ATTR_SHOW_FMT(_prop, _attrname, _fmt, _val) \
-+static ssize_t _attrname##_##_prop##_show(struct kobject *kobj, \
-+ struct kobj_attribute *attr, char *buf) \
-+{ \
-+ return sysfs_emit(buf, _fmt, _val); \
-+} \
-+static struct kobj_attribute attr_##_attrname##_##_prop = \
-+ __ASUS_ATTR_RO(_attrname, _prop)
-+
-+/* Boolean style enumeration, base macro. Requires adding show/store */
-+#define __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname) \
-+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-+__ATTR_SHOW_FMT(possible_values, _attrname, "%s\n", _possible); \
-+static struct kobj_attribute attr_##_attrname##_type = \
-+ __ASUS_ATTR_RO_AS(type, enum_type_show); \
-+static struct attribute *_attrname##_attrs[] = { \
-+ &attr_##_attrname##_current_value.attr, \
-+ &attr_##_attrname##_display_name.attr, \
-+ &attr_##_attrname##_possible_values.attr, \
-+ &attr_##_attrname##_type.attr, \
-+ NULL \
-+}; \
-+static const struct attribute_group _attrname##_attr_group = { \
-+ .name = _fsname, \
-+ .attrs = _attrname##_attrs \
-+}
-+
-+#define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \
-+ __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
-+ __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
-+
-+#define ATTR_GROUP_BOOL_RW(_attrname, _fsname, _wmi, _dispname) \
-+ __ATTR_CURRENT_INT_RW(_attrname, 0, 1, _wmi); \
-+ __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
-+
-+/*
-+ * Requires _current_value_show(), _current_value_show()
-+ */
-+#define ATTR_GROUP_BOOL_CUSTOM(_attrname, _fsname, _dispname) \
-+static struct kobj_attribute attr_##_attrname##_current_value = \
-+ __ASUS_ATTR_RW(_attrname, current_value); \
-+ __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname)
-+
-+#define ATTR_GROUP_ENUM_INT_RO(_attrname, _fsname, _wmi, \
-+ _possible, _dispname) \
-+ __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
-+ __ATTR_GROUP_ENUM(_attrname, _fsname, _possible, _dispname)
-+
-+/*
-+ * Requires _current_value_show(), _current_value_show()
-+ * and _possible_values_show()
-+ */
-+#define ATTR_GROUP_ENUM_CUSTOM(_attrname, _fsname, _dispname) \
-+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-+static struct kobj_attribute attr_##_attrname##_current_value = \
-+ __ASUS_ATTR_RW(_attrname, current_value); \
-+static struct kobj_attribute attr_##_attrname##_possible_values = \
-+ __ASUS_ATTR_RO(_attrname, possible_values); \
-+static struct kobj_attribute attr_##_attrname##_type = \
-+ __ASUS_ATTR_RO_AS(type, enum_type_show); \
-+static struct attribute *_attrname##_attrs[] = { \
-+ &attr_##_attrname##_current_value.attr, \
-+ &attr_##_attrname##_display_name.attr, \
-+ &attr_##_attrname##_possible_values.attr, \
-+ &attr_##_attrname##_type.attr, \
-+ NULL \
-+}; \
-+static const struct attribute_group _attrname##_attr_group = { \
-+ .name = _fsname, \
-+ .attrs = _attrname##_attrs \
-+}
-+
-+/*
-+ * ROG PPT attributes need a little different in setup as they
-+ * require rog_tunables members.
-+ */
-+
-+#define __ROG_TUNABLE_RW(_attr, _min, _max, _wmi) \
-+static ssize_t _attr##_current_value_store(struct kobject *kobj, \
-+ struct kobj_attribute *attr, \
-+ const char *buf, size_t count) \
-+{ \
-+ return attr_int_store(kobj, attr, buf, count, \
-+ asus_armoury.rog_tunables->_min, \
-+ asus_armoury.rog_tunables->_max, \
-+ &asus_armoury.rog_tunables->_attr, _wmi); \
-+} \
-+static ssize_t _attr##_current_value_show(struct kobject *kobj, \
-+ struct kobj_attribute *attr, char *buf) \
-+{ \
-+ return sysfs_emit(buf, "%u\n", asus_armoury.rog_tunables->_attr);\
-+} \
-+static struct kobj_attribute attr_##_attr##_current_value = \
-+ __ASUS_ATTR_RW(_attr, current_value)
-+
-+#define __ROG_TUNABLE_SHOW(_prop, _attrname, _val) \
-+static ssize_t _attrname##_##_prop##_show(struct kobject *kobj, \
-+ struct kobj_attribute *attr, char *buf) \
-+{ \
-+ return sysfs_emit(buf, "%d\n", asus_armoury.rog_tunables->_val);\
-+} \
-+static struct kobj_attribute attr_##_attrname##_##_prop = \
-+ __ASUS_ATTR_RO(_attrname, _prop)
-+
-+#define ATTR_GROUP_ROG_TUNABLE(_attrname, _fsname, _wmi, _default, \
-+ _min, _max, _incstep, _dispname) \
-+__ROG_TUNABLE_SHOW(default_value, _attrname, _default); \
-+__ROG_TUNABLE_RW(_attrname, _min, _max, _wmi); \
-+__ROG_TUNABLE_SHOW(min_value, _attrname, _min); \
-+__ROG_TUNABLE_SHOW(max_value, _attrname, _max); \
-+__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", _incstep); \
-+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-+static struct kobj_attribute attr_##_attrname##_type = \
-+ __ASUS_ATTR_RO_AS(type, int_type_show); \
-+static struct attribute *_attrname##_attrs[] = { \
-+ &attr_##_attrname##_current_value.attr, \
-+ &attr_##_attrname##_default_value.attr, \
-+ &attr_##_attrname##_min_value.attr, \
-+ &attr_##_attrname##_max_value.attr, \
-+ &attr_##_attrname##_scalar_increment.attr, \
-+ &attr_##_attrname##_display_name.attr, \
-+ &attr_##_attrname##_type.attr, \
-+ NULL \
-+}; \
-+static const struct attribute_group _attrname##_attr_group = { \
-+ .name = _fsname, \
-+ .attrs = _attrname##_attrs \
-+}
-+
-+#endif /* _ASUS_BIOSCFG_H_ */
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 26684d78625e..ece00bef3864 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -155,20 +155,6 @@ static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
-
- static int throttle_thermal_policy_write(struct asus_wmi *);
-
--static const struct dmi_system_id asus_rog_ally_device[] = {
-- {
-- .matches = {
-- DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
-- },
-- },
-- {
-- .matches = {
-- DMI_MATCH(DMI_BOARD_NAME, "RC72L"),
-- },
-- },
-- { },
--};
--
- static bool ashs_present(void)
- {
- int i = 0;
-@@ -552,12 +538,59 @@ static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
- return 0;
- }
-
--static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
-- u32 *retval)
-+/**
-+ * asus_wmi_get_devstate_dsts() - Get the WMI function state.
-+ * @dev_id: The WMI function to call.
-+ * @retval: A pointer to where to store the value returned from WMI.
-+ *
-+ * The returned WMI function state can also be used to determine if the WMI
-+ * function is supported by checking if the asus_wmi_get_devstate_dsts()
-+ * returns an error.
-+ *
-+ * On success the return value is 0, and the retval is a valid value returned
-+ * by the successful WMI function call. An error value is returned only if the
-+ * WMI function failed, or if it returns "unsupported" which is typically a 0
-+ * (no return, and no 'supported' bit set), or a 0xFFFFFFFE (~1) which if not
-+ * caught here can result in unexpected behaviour later.
-+ */
-+int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
-+ {
-+ int err;
-+
-+ err = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0, retval);
-+ *retval &= ~ASUS_WMI_DSTS_PRESENCE_BIT;
-+
-+ if (err)
-+ return err;
-+ /* Be explicit about retval */
-+ if (*retval == ASUS_WMI_UNSUPPORTED_METHOD)
-+ return -ENODEV;
-+
-+ return 0;
-+ }
-+
-+EXPORT_SYMBOL_GPL(asus_wmi_get_devstate_dsts);
-+
-+/**
-+ * asus_wmi_set_devstate() - Set the WMI function state.
-+ * @dev_id: The WMI function to call.
-+ * @ctrl_param: The argument to be used for this WMI function.
-+ * @retval: A pointer to where to store the value returned from WMI.
-+ *
-+ * The returned WMI function state if not checked here for error as
-+ * asus_wmi_set_devstate() is not called unless first paired with a call to
-+ * asus_wmi_get_devstate_dsts() to check that the WMI function is supported.
-+ *
-+ * On success the return value is 0, and the retval is a valid value returned
-+ * by the successful WMI function call. An error value is returned only if the
-+ * WMI function failed.
-+ */
-+int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval)
- {
- return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
- ctrl_param, retval);
- }
-+EXPORT_SYMBOL_GPL(asus_wmi_set_devstate);
-
- /* Helper for special devices with magic return codes */
- static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
-diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
-index d02f15fd3482..c66e970b3674 100644
---- a/drivers/platform/x86/asus-wmi.h
-+++ b/drivers/platform/x86/asus-wmi.h
-@@ -86,4 +86,18 @@ struct asus_wmi_driver {
- int asus_wmi_register_driver(struct asus_wmi_driver *driver);
- void asus_wmi_unregister_driver(struct asus_wmi_driver *driver);
-
-+static const struct dmi_system_id asus_rog_ally_device[] = {
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "RC72L"),
-+ },
-+ },
-+ { },
-+};
-+
- #endif /* !_ASUS_WMI_H_ */
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 365e119bebaa..7caf2c7ed8c9 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -73,6 +73,7 @@
- #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019
-
- /* Misc */
-+#define ASUS_WMI_DEVID_PANEL_HD 0x0005001C
- #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
- #define ASUS_WMI_DEVID_CAMERA 0x00060013
- #define ASUS_WMI_DEVID_LID_FLIP 0x00060062
-@@ -158,8 +159,18 @@
- #define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F
-
- #if IS_REACHABLE(CONFIG_ASUS_WMI)
-+int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval);
-+int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval);
- int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
- #else
-+static inline int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
-+{
-+ return -ENODEV;
-+}
-+static inline int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval)
-+{
-+ return -ENODEV;
-+}
- static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
- u32 *retval)
- {
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0015-platform-x86-asus-wmi-deprecate-bios-features.patch b/packages/l/linux-current/files/patches/hardware/asus/0012-platform-x86-asus-wmi-deprecate-bios-features.patch
similarity index 75%
rename from packages/l/linux-current/files/patches/hardware/asus/0015-platform-x86-asus-wmi-deprecate-bios-features.patch
rename to packages/l/linux-current/files/patches/hardware/asus/0012-platform-x86-asus-wmi-deprecate-bios-features.patch
index 8ce2fa879cf..5f43cd9f043 100644
--- a/packages/l/linux-current/files/patches/hardware/asus/0015-platform-x86-asus-wmi-deprecate-bios-features.patch
+++ b/packages/l/linux-current/files/patches/hardware/asus/0012-platform-x86-asus-wmi-deprecate-bios-features.patch
@@ -1,20 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones"
Date: Mon, 3 Jun 2024 12:04:41 +1200
-Subject: [PATCH 15/18] platform/x86: asus-wmi: deprecate bios features
+Subject: [PATCH 12/27] platform/x86: asus-wmi: deprecate bios features
-With the existence of the asus-bioscfg module the attributes no-longer
+With the existence of the asus-armoury module the attributes no-longer
need to live under the /sys/devices/platform/asus-nb-wmi/ path.
Deprecate all those that were implemented in asus-bioscfg with the goal
of removing them fully in the next LTS cycle.
Signed-off-by: Luke D. Jones
+Reviewed-by: Mario Limonciello
---
.../ABI/testing/sysfs-platform-asus-wmi | 17 +++
- drivers/platform/x86/Kconfig | 8 ++
+ drivers/platform/x86/Kconfig | 9 ++
drivers/platform/x86/asus-wmi.c | 134 ++++++++++++++----
- 3 files changed, 129 insertions(+), 30 deletions(-)
+ 3 files changed, 130 insertions(+), 30 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
index 28144371a0f1..765d50b0d9df 100644
@@ -157,35 +158,36 @@ index 28144371a0f1..765d50b0d9df 100644
* 0 - False,
* 1 - True
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index d13c4085c228..01f780d53793 100644
+index 80ec8b45022d..d0fc68d93f48 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
-@@ -301,6 +301,14 @@ config ASUS_WMI
+@@ -299,6 +299,15 @@ config ASUS_WMI
To compile this driver as a module, choose M here: the module will
be called asus-wmi.
-+config ASUS_WMI_BIOS
++config ASUS_WMI_DEPRECATED_ATTRS
+ bool "BIOS option support in WMI platform (DEPRECATED)"
+ depends on ASUS_WMI
++ default y
+ help
+ Say Y to expose the configurable BIOS options through the asus-wmi
-+ driver. This can be used with or without the new asus-bios driver as
-+ the options are the same but the asus-bios driver has more features.
++ driver. This can be used with or without the asus-armoury driver which
++ has the same attributes, but more, and better features.
+
config ASUS_NB_WMI
tristate "Asus Notebook WMI Driver"
depends on ASUS_WMI
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index ece00bef3864..c654bf45b670 100644
+index 525629097b9f..d4981e08f44f 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
-@@ -276,11 +276,12 @@ struct asus_wmi {
+@@ -286,11 +286,12 @@ struct asus_wmi {
u8 fan_boost_mode_mask;
u8 fan_boost_mode;
+
+ /* Tunables provided by ASUS for gaming laptops */
-+ #if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
bool egpu_enable_available;
bool dgpu_disable_available;
u32 gpu_mux_dev;
@@ -194,17 +196,17 @@ index ece00bef3864..c654bf45b670 100644
u32 ppt_pl2_sppt;
u32 ppt_pl1_spl;
u32 ppt_apu_sppt;
-@@ -288,6 +289,9 @@ struct asus_wmi {
+@@ -298,6 +299,9 @@ struct asus_wmi {
u32 ppt_fppt;
u32 nv_dynamic_boost;
u32 nv_temp_target;
+ bool panel_overdrive_available;
+ u32 mini_led_dev_id;
-+ #endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
u32 kbd_rgb_dev;
bool kbd_rgb_state_available;
-@@ -306,9 +310,6 @@ struct asus_wmi {
+@@ -316,9 +320,6 @@ struct asus_wmi {
// The RSOC controls the maximum charging percentage.
bool battery_rsoc_available;
@@ -214,31 +216,31 @@ index ece00bef3864..c654bf45b670 100644
struct hotplug_slot hotplug_slot;
struct mutex hotplug_lock;
struct mutex wmi_lock;
-@@ -324,6 +325,15 @@ struct asus_wmi {
+@@ -334,6 +335,15 @@ struct asus_wmi {
- static bool ally_mcu_usb_switch;
+ static bool ally_mcu_usb_plug;
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
+static void asus_wmi_show_deprecated(void)
+{
-+ pr_notice_once("Accessing attributes through /sys/bus/platform/asus_wmi is \
-+ deprecated and will be removed in a future release. Please switch \
-+ over to /sys/class/firmware_attributes.");
++ pr_notice_once("Accessing attributes through /sys/bus/platform/asus_wmi "
++ "is deprecated and will be removed in a future release. Please "
++ "switch over to /sys/class/firmware_attributes.\n");
+}
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
+
/* WMI ************************************************************************/
static int asus_wmi_evaluate_method3(u32 method_id,
-@@ -723,6 +733,7 @@ static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus)
+@@ -724,6 +734,7 @@ static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus)
}
/* Charging mode, 1=Barrel, 2=USB ******************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t charge_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -733,12 +744,16 @@ static ssize_t charge_mode_show(struct device *dev,
+@@ -734,12 +745,16 @@ static ssize_t charge_mode_show(struct device *dev,
if (result < 0)
return result;
@@ -248,14 +250,14 @@ index ece00bef3864..c654bf45b670 100644
}
static DEVICE_ATTR_RO(charge_mode);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* dGPU ********************************************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t dgpu_disable_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -749,6 +764,8 @@ static ssize_t dgpu_disable_show(struct device *dev,
+@@ -750,6 +765,8 @@ static ssize_t dgpu_disable_show(struct device *dev,
if (result < 0)
return result;
@@ -264,18 +266,18 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%d\n", result);
}
-@@ -802,8 +819,10 @@ static ssize_t dgpu_disable_store(struct device *dev,
+@@ -803,8 +820,10 @@ static ssize_t dgpu_disable_store(struct device *dev,
return count;
}
static DEVICE_ATTR_RW(dgpu_disable);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* eGPU ********************************************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t egpu_enable_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -814,6 +833,8 @@ static ssize_t egpu_enable_show(struct device *dev,
+@@ -815,6 +834,8 @@ static ssize_t egpu_enable_show(struct device *dev,
if (result < 0)
return result;
@@ -284,18 +286,18 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%d\n", result);
}
-@@ -870,8 +891,10 @@ static ssize_t egpu_enable_store(struct device *dev,
+@@ -871,8 +892,10 @@ static ssize_t egpu_enable_store(struct device *dev,
return count;
}
static DEVICE_ATTR_RW(egpu_enable);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* Is eGPU connected? *********************************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t egpu_connected_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -882,12 +905,16 @@ static ssize_t egpu_connected_show(struct device *dev,
+@@ -883,12 +906,16 @@ static ssize_t egpu_connected_show(struct device *dev,
if (result < 0)
return result;
@@ -305,14 +307,14 @@ index ece00bef3864..c654bf45b670 100644
}
static DEVICE_ATTR_RO(egpu_connected);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* gpu mux switch *************************************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t gpu_mux_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -898,6 +925,8 @@ static ssize_t gpu_mux_mode_show(struct device *dev,
+@@ -899,6 +926,8 @@ static ssize_t gpu_mux_mode_show(struct device *dev,
if (result < 0)
return result;
@@ -321,23 +323,23 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%d\n", result);
}
-@@ -956,6 +985,7 @@ static ssize_t gpu_mux_mode_store(struct device *dev,
+@@ -957,6 +986,7 @@ static ssize_t gpu_mux_mode_store(struct device *dev,
return count;
}
static DEVICE_ATTR_RW(gpu_mux_mode);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* TUF Laptop Keyboard RGB Modes **********************************************/
static ssize_t kbd_rgb_mode_store(struct device *dev,
-@@ -1079,6 +1109,7 @@ static const struct attribute_group *kbd_rgb_mode_groups[] = {
+@@ -1080,6 +1110,7 @@ static const struct attribute_group *kbd_rgb_mode_groups[] = {
};
/* Tunable: PPT: Intel=PL1, AMD=SPPT *****************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t ppt_pl2_sppt_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
-@@ -1117,6 +1148,8 @@ static ssize_t ppt_pl2_sppt_show(struct device *dev,
+@@ -1118,6 +1149,8 @@ static ssize_t ppt_pl2_sppt_show(struct device *dev,
{
struct asus_wmi *asus = dev_get_drvdata(dev);
@@ -346,7 +348,7 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%u\n", asus->ppt_pl2_sppt);
}
static DEVICE_ATTR_RW(ppt_pl2_sppt);
-@@ -1159,6 +1192,8 @@ static ssize_t ppt_pl1_spl_show(struct device *dev,
+@@ -1160,6 +1193,8 @@ static ssize_t ppt_pl1_spl_show(struct device *dev,
{
struct asus_wmi *asus = dev_get_drvdata(dev);
@@ -355,7 +357,7 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%u\n", asus->ppt_pl1_spl);
}
static DEVICE_ATTR_RW(ppt_pl1_spl);
-@@ -1202,6 +1237,8 @@ static ssize_t ppt_fppt_show(struct device *dev,
+@@ -1203,6 +1238,8 @@ static ssize_t ppt_fppt_show(struct device *dev,
{
struct asus_wmi *asus = dev_get_drvdata(dev);
@@ -364,7 +366,7 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%u\n", asus->ppt_fppt);
}
static DEVICE_ATTR_RW(ppt_fppt);
-@@ -1245,6 +1282,8 @@ static ssize_t ppt_apu_sppt_show(struct device *dev,
+@@ -1246,6 +1283,8 @@ static ssize_t ppt_apu_sppt_show(struct device *dev,
{
struct asus_wmi *asus = dev_get_drvdata(dev);
@@ -373,7 +375,7 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%u\n", asus->ppt_apu_sppt);
}
static DEVICE_ATTR_RW(ppt_apu_sppt);
-@@ -1288,6 +1327,8 @@ static ssize_t ppt_platform_sppt_show(struct device *dev,
+@@ -1289,6 +1328,8 @@ static ssize_t ppt_platform_sppt_show(struct device *dev,
{
struct asus_wmi *asus = dev_get_drvdata(dev);
@@ -382,7 +384,7 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%u\n", asus->ppt_platform_sppt);
}
static DEVICE_ATTR_RW(ppt_platform_sppt);
-@@ -1331,6 +1372,8 @@ static ssize_t nv_dynamic_boost_show(struct device *dev,
+@@ -1332,6 +1373,8 @@ static ssize_t nv_dynamic_boost_show(struct device *dev,
{
struct asus_wmi *asus = dev_get_drvdata(dev);
@@ -391,7 +393,7 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%u\n", asus->nv_dynamic_boost);
}
static DEVICE_ATTR_RW(nv_dynamic_boost);
-@@ -1374,11 +1417,15 @@ static ssize_t nv_temp_target_show(struct device *dev,
+@@ -1375,11 +1418,15 @@ static ssize_t nv_temp_target_show(struct device *dev,
{
struct asus_wmi *asus = dev_get_drvdata(dev);
@@ -400,14 +402,14 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%u\n", asus->nv_temp_target);
}
static DEVICE_ATTR_RW(nv_temp_target);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* Ally MCU Powersave ********************************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t mcu_powersave_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -1389,6 +1436,8 @@ static ssize_t mcu_powersave_show(struct device *dev,
+@@ -1390,6 +1437,8 @@ static ssize_t mcu_powersave_show(struct device *dev,
if (result < 0)
return result;
@@ -416,23 +418,23 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%d\n", result);
}
-@@ -1424,6 +1473,7 @@ static ssize_t mcu_powersave_store(struct device *dev,
+@@ -1425,6 +1474,7 @@ static ssize_t mcu_powersave_store(struct device *dev,
return count;
}
static DEVICE_ATTR_RW(mcu_powersave);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* Battery ********************************************************************/
-@@ -2297,6 +2347,7 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
+@@ -2298,6 +2348,7 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
}
/* Panel Overdrive ************************************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t panel_od_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -2307,6 +2358,8 @@ static ssize_t panel_od_show(struct device *dev,
+@@ -2308,6 +2359,8 @@ static ssize_t panel_od_show(struct device *dev,
if (result < 0)
return result;
@@ -441,19 +443,19 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%d\n", result);
}
-@@ -2343,9 +2396,10 @@ static ssize_t panel_od_store(struct device *dev,
+@@ -2344,9 +2397,10 @@ static ssize_t panel_od_store(struct device *dev,
return count;
}
static DEVICE_ATTR_RW(panel_od);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* Bootup sound ***************************************************************/
-
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t boot_sound_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -2356,6 +2410,8 @@ static ssize_t boot_sound_show(struct device *dev,
+@@ -2357,6 +2411,8 @@ static ssize_t boot_sound_show(struct device *dev,
if (result < 0)
return result;
@@ -462,18 +464,18 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%d\n", result);
}
-@@ -2391,8 +2447,10 @@ static ssize_t boot_sound_store(struct device *dev,
+@@ -2392,8 +2448,10 @@ static ssize_t boot_sound_store(struct device *dev,
return count;
}
static DEVICE_ATTR_RW(boot_sound);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* Mini-LED mode **************************************************************/
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t mini_led_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -2423,6 +2481,8 @@ static ssize_t mini_led_mode_show(struct device *dev,
+@@ -2424,6 +2482,8 @@ static ssize_t mini_led_mode_show(struct device *dev,
}
}
@@ -482,7 +484,7 @@ index ece00bef3864..c654bf45b670 100644
return sysfs_emit(buf, "%d\n", value);
}
-@@ -2493,10 +2553,13 @@ static ssize_t available_mini_led_mode_show(struct device *dev,
+@@ -2494,10 +2554,13 @@ static ssize_t available_mini_led_mode_show(struct device *dev,
return sysfs_emit(buf, "0 1 2\n");
}
@@ -492,27 +494,27 @@ index ece00bef3864..c654bf45b670 100644
}
static DEVICE_ATTR_RO(available_mini_led_mode);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* Quirks *********************************************************************/
-@@ -3795,6 +3858,7 @@ static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
+@@ -3807,6 +3870,7 @@ static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
return 0;
}
-+#if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
static ssize_t throttle_thermal_policy_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -3838,6 +3902,7 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
+@@ -3850,6 +3914,7 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
* Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
*/
static DEVICE_ATTR_RW(throttle_thermal_policy);
-+#endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
/* Platform profile ***********************************************************/
- static int asus_wmi_platform_profile_to_vivo(struct asus_wmi *asus, int mode)
-@@ -4478,27 +4543,29 @@ static struct attribute *platform_attributes[] = {
+ static int asus_wmi_platform_profile_get(struct platform_profile_handler *pprof,
+@@ -4447,27 +4512,29 @@ static struct attribute *platform_attributes[] = {
&dev_attr_camera.attr,
&dev_attr_cardr.attr,
&dev_attr_touchpad.attr,
@@ -537,7 +539,7 @@ index ece00bef3864..c654bf45b670 100644
- &dev_attr_panel_od.attr,
- &dev_attr_mini_led_mode.attr,
- &dev_attr_available_mini_led_mode.attr,
-+ #if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
+ &dev_attr_charge_mode.attr,
+ &dev_attr_egpu_enable.attr,
+ &dev_attr_egpu_connected.attr,
@@ -556,11 +558,11 @@ index ece00bef3864..c654bf45b670 100644
+ &dev_attr_mini_led_mode.attr,
+ &dev_attr_available_mini_led_mode.attr,
+ &dev_attr_throttle_thermal_policy.attr,
-+ #endif
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
NULL
};
-@@ -4520,7 +4587,11 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
+@@ -4489,7 +4556,11 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
devid = ASUS_WMI_DEVID_LID_RESUME;
else if (attr == &dev_attr_als_enable.attr)
devid = ASUS_WMI_DEVID_ALS_ENABLE;
@@ -568,37 +570,38 @@ index ece00bef3864..c654bf45b670 100644
+ else if (attr == &dev_attr_fan_boost_mode.attr)
+ ok = asus->fan_boost_mode_available;
+
-+ #if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
+ if (attr == &dev_attr_charge_mode.attr)
devid = ASUS_WMI_DEVID_CHARGE_MODE;
else if (attr == &dev_attr_egpu_enable.attr)
ok = asus->egpu_enable_available;
-@@ -4565,6 +4636,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- */
- if (attr == &dev_attr_mcu_powersave.attr)
- return 0;
-+ #endif
+@@ -4527,6 +4598,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
+ ok = asus->mini_led_dev_id != 0;
+ else if (attr == &dev_attr_available_mini_led_mode.attr)
+ ok = asus->mini_led_dev_id != 0;
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
if (devid != -1) {
ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
-@@ -4821,6 +4893,7 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -4778,6 +4850,7 @@ static int asus_wmi_add(struct platform_device *pdev)
}
/* ensure defaults for tunables */
-+ #if IS_ENABLED(CONFIG_ASUS_WMI_BIOS)
++#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
asus->ppt_pl2_sppt = 5;
asus->ppt_pl1_spl = 5;
asus->ppt_apu_sppt = 5;
-@@ -4843,16 +4916,17 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -4799,17 +4872,18 @@ static int asus_wmi_add(struct platform_device *pdev)
+ asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX;
else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO))
asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO;
-
+-
- if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE))
- asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE;
- else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2))
- asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2;
--
-+ #endif /* CONFIG_ASUS_WMI_BIOS */
++#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
+
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY;
else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO))
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0013-ALSA-hda-realtek-fixup-ASUS-GA605W.patch b/packages/l/linux-current/files/patches/hardware/asus/0013-ALSA-hda-realtek-fixup-ASUS-GA605W.patch
new file mode 100644
index 00000000000..b3a8f236953
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0013-ALSA-hda-realtek-fixup-ASUS-GA605W.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Thu, 10 Oct 2024 09:52:45 +1300
+Subject: [PATCH 13/27] ALSA: hda/realtek: fixup ASUS GA605W
+
+The GA605W laptop has almost the exact same codec setup as the GA403
+and so the same quirks apply to it.
+
+Signed-off-by: Luke D. Jones
+---
+ sound/pci/hda/patch_realtek.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 973671e0cdb0..bfb3e95ccfaf 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10603,6 +10603,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1e1f, "ASUS Vivobook 15 X1504VAP", ALC2XX_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
+ SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
++ SND_PCI_QUIRK(0x1043, 0x1e63, "ASUS H7606W", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC),
++ SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0014-hid-asus-ally-Add-joystick-LED-ring-support.patch b/packages/l/linux-current/files/patches/hardware/asus/0014-hid-asus-ally-Add-joystick-LED-ring-support.patch
new file mode 100644
index 00000000000..28256e88f8e
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0014-hid-asus-ally-Add-joystick-LED-ring-support.patch
@@ -0,0 +1,780 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Mon, 26 Aug 2024 12:49:35 +1200
+Subject: [PATCH 14/27] hid-asus-ally: Add joystick LED ring support
+
+Adds basic support for the joystick RGB LED rings as a multicolour LED
+device with 4 LEDs.
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/Kconfig | 9 +
+ drivers/hid/Makefile | 1 +
+ drivers/hid/hid-asus-ally.c | 625 ++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-asus-ally.h | 38 +++
+ drivers/hid/hid-asus.c | 20 +-
+ 5 files changed, 691 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/hid/hid-asus-ally.c
+ create mode 100644 drivers/hid/hid-asus-ally.h
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index f8a56d631242..d477df3a3f35 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -164,6 +164,15 @@ config HID_ASUS
+ - GL553V series
+ - GL753V series
+
++config HID_ASUS_ALLY
++ tristate "Asus Ally gamepad configuration support"
++ depends on USB_HID
++ depends on LEDS_CLASS
++ depends on LEDS_CLASS_MULTICOLOR
++ select POWER_SUPPLY
++ help
++ Support for configuring the Asus ROG Ally gamepad using attributes.
++
+ config HID_AUREAL
+ tristate "Aureal"
+ help
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index 496dab54c73a..5fa65e1e1e3b 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -31,6 +31,7 @@ obj-$(CONFIG_HID_APPLE) += hid-apple.o
+ obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o
+ obj-$(CONFIG_HID_CREATIVE_SB0540) += hid-creative-sb0540.o
+ obj-$(CONFIG_HID_ASUS) += hid-asus.o
++obj-$(CONFIG_HID_ASUS_ALLY) += hid-asus-ally.o
+ obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
+ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
+ obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+new file mode 100644
+index 000000000000..bfadf5cd700d
+--- /dev/null
++++ b/drivers/hid/hid-asus-ally.c
+@@ -0,0 +1,625 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * HID driver for Asus ROG laptops and Ally
++ *
++ * Copyright (c) 2023 Luke Jones
++ */
++
++#include "linux/device.h"
++#include "linux/err.h"
++#include "linux/kstrtox.h"
++#include "linux/pm.h"
++#include "linux/slab.h"
++#include "linux/stddef.h"
++#include
++#include
++#include
++#include
++#include
++
++#include "hid-ids.h"
++#include "hid-asus-ally.h"
++
++#define READY_MAX_TRIES 3
++#define FEATURE_REPORT_ID 0x0d
++#define FEATURE_ROG_ALLY_REPORT_ID 0x5a
++#define FEATURE_ROG_ALLY_CODE_PAGE 0xD1
++#define FEATURE_ROG_ALLY_REPORT_SIZE 64
++#define ALLY_X_INPUT_REPORT_USB 0x0B
++#define ALLY_X_INPUT_REPORT_USB_SIZE 16
++
++#define ALLY_CFG_INTF_IN_ADDRESS 0x83
++#define ALLY_CFG_INTF_OUT_ADDRESS 0x04
++#define ALLY_X_INTERFACE_ADDRESS 0x87
++
++#define FEATURE_KBD_LED_REPORT_ID1 0x5d
++#define FEATURE_KBD_LED_REPORT_ID2 0x5e
++
++#define ALLY_MIN_BIOS 319
++#define ALLY_X_MIN_BIOS 313
++
++static const u8 EC_INIT_STRING[] = { 0x5A, 'A', 'S', 'U', 'S', ' ', 'T', 'e','c', 'h', '.', 'I', 'n', 'c', '.', '\0' };
++static const u8 EC_MODE_LED_APPLY[] = { 0x5A, 0xB4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
++static const u8 EC_MODE_LED_SET[] = { 0x5A, 0xB5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
++static const u8 FORCE_FEEDBACK_OFF[] = { 0x0D, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB };
++
++static const struct hid_device_id rog_ally_devices[] = {
++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X) },
++ {}
++};
++
++struct ally_rgb_dev {
++ struct hid_device *hdev;
++ struct led_classdev_mc led_rgb_dev;
++ struct work_struct work;
++ bool output_worker_initialized;
++ spinlock_t lock;
++
++ bool removed;
++ bool update_rgb;
++ uint8_t red[4];
++ uint8_t green[4];
++ uint8_t blue[4];
++};
++
++struct ally_rgb_data {
++ uint8_t brightness;
++ uint8_t red[4];
++ uint8_t green[4];
++ uint8_t blue[4];
++ bool initialized;
++};
++
++static struct ally_drvdata {
++ struct hid_device *hdev;
++ struct ally_rgb_dev *led_rgb_dev;
++ struct ally_rgb_data led_rgb_data;
++} drvdata;
++
++static int asus_dev_get_report(struct hid_device *hdev, u8 *out_buf, size_t out_buf_size)
++{
++ return hid_hw_raw_request(hdev, FEATURE_REPORT_ID, out_buf, out_buf_size,
++ HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
++}
++
++/**
++ * asus_dev_set_report - send set report request to device.
++ *
++ * @hdev: hid device
++ * @buf: in/out data to transfer
++ * @len: length of buf
++ *
++ * Return: count of data transferred, negative if error
++ *
++ * Same behavior as hid_hw_raw_request. Note that the input buffer is duplicated.
++ */
++static int asus_dev_set_report(struct hid_device *hdev, const u8 *buf, size_t len)
++{
++ unsigned char *dmabuf;
++ int ret;
++
++ dmabuf = kmemdup(buf, len, GFP_KERNEL);
++ if (!dmabuf)
++ return -ENOMEM;
++
++ ret = hid_hw_raw_request(hdev, buf[0], dmabuf, len, HID_FEATURE_REPORT,
++ HID_REQ_SET_REPORT);
++ kfree(dmabuf);
++
++ return ret;
++}
++
++static u8 get_endpoint_address(struct hid_device *hdev)
++{
++ struct usb_interface *intf;
++ struct usb_host_endpoint *ep;
++
++ intf = to_usb_interface(hdev->dev.parent);
++
++ if (intf) {
++ ep = intf->cur_altsetting->endpoint;
++ if (ep) {
++ return ep->desc.bEndpointAddress;
++ }
++ }
++
++ return -ENODEV;
++}
++
++/**************************************************************************************************/
++/* ROG Ally LED control */
++/**************************************************************************************************/
++static void ally_rgb_schedule_work(struct ally_rgb_dev *led)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&led->lock, flags);
++ if (!led->removed)
++ schedule_work(&led->work);
++ spin_unlock_irqrestore(&led->lock, flags);
++}
++
++/*
++ * The RGB still has the basic 0-3 level brightness. Since the multicolour
++ * brightness is being used in place, set this to max
++ */
++static int ally_rgb_set_bright_base_max(struct hid_device *hdev)
++{
++ u8 buf[] = { FEATURE_KBD_LED_REPORT_ID1, 0xba, 0xc5, 0xc4, 0x02 };
++
++ return asus_dev_set_report(hdev, buf, sizeof(buf));
++}
++
++static void ally_rgb_do_work(struct work_struct *work)
++{
++ struct ally_rgb_dev *led = container_of(work, struct ally_rgb_dev, work);
++ int ret;
++ unsigned long flags;
++
++ u8 buf[16] = { [0] = FEATURE_ROG_ALLY_REPORT_ID,
++ [1] = FEATURE_ROG_ALLY_CODE_PAGE,
++ [2] = xpad_cmd_set_leds,
++ [3] = xpad_cmd_len_leds };
++
++ spin_lock_irqsave(&led->lock, flags);
++ if (!led->update_rgb) {
++ spin_unlock_irqrestore(&led->lock, flags);
++ return;
++ }
++
++ for (int i = 0; i < 4; i++) {
++ buf[5 + i * 3] = drvdata.led_rgb_dev->green[i];
++ buf[6 + i * 3] = drvdata.led_rgb_dev->blue[i];
++ buf[4 + i * 3] = drvdata.led_rgb_dev->red[i];
++ }
++ led->update_rgb = false;
++
++ spin_unlock_irqrestore(&led->lock, flags);
++
++ ret = asus_dev_set_report(led->hdev, buf, sizeof(buf));
++ if (ret < 0)
++ hid_err(led->hdev, "Ally failed to set gamepad backlight: %d\n", ret);
++}
++
++static void ally_rgb_set(struct led_classdev *cdev, enum led_brightness brightness)
++{
++ struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
++ struct ally_rgb_dev *led = container_of(mc_cdev, struct ally_rgb_dev, led_rgb_dev);
++ int intensity, bright;
++ unsigned long flags;
++
++ led_mc_calc_color_components(mc_cdev, brightness);
++ spin_lock_irqsave(&led->lock, flags);
++ led->update_rgb = true;
++ bright = mc_cdev->led_cdev.brightness;
++ for (int i = 0; i < 4; i++) {
++ intensity = mc_cdev->subled_info[i].intensity;
++ drvdata.led_rgb_dev->red[i] = (((intensity >> 16) & 0xFF) * bright) / 255;
++ drvdata.led_rgb_dev->green[i] = (((intensity >> 8) & 0xFF) * bright) / 255;
++ drvdata.led_rgb_dev->blue[i] = ((intensity & 0xFF) * bright) / 255;
++ }
++ spin_unlock_irqrestore(&led->lock, flags);
++ drvdata.led_rgb_data.initialized = true;
++
++ ally_rgb_schedule_work(led);
++}
++
++static int ally_rgb_set_static_from_multi(struct hid_device *hdev)
++{
++ u8 buf[17] = {FEATURE_KBD_LED_REPORT_ID1, 0xb3};
++ int ret;
++
++ /*
++ * Set single zone single colour based on the first LED of EC software mode.
++ * buf[2] = zone, buf[3] = mode
++ */
++ buf[4] = drvdata.led_rgb_data.red[0];
++ buf[5] = drvdata.led_rgb_data.green[0];
++ buf[6] = drvdata.led_rgb_data.blue[0];
++
++ ret = asus_dev_set_report(hdev, buf, sizeof(buf));
++ if (ret < 0)
++ return ret;
++
++ ret = asus_dev_set_report(hdev, EC_MODE_LED_APPLY, sizeof(EC_MODE_LED_APPLY));
++ if (ret < 0)
++ return ret;
++
++ return asus_dev_set_report(hdev, EC_MODE_LED_SET, sizeof(EC_MODE_LED_SET));
++}
++
++/*
++ * Store the RGB values for restoring on resume, and set the static mode to the first LED colour
++*/
++static void ally_rgb_store_settings(void)
++{
++ int arr_size = sizeof(drvdata.led_rgb_data.red);
++
++ struct ally_rgb_dev *led_rgb = drvdata.led_rgb_dev;
++
++ drvdata.led_rgb_data.brightness = led_rgb->led_rgb_dev.led_cdev.brightness;
++
++ memcpy(drvdata.led_rgb_data.red, led_rgb->red, arr_size);
++ memcpy(drvdata.led_rgb_data.green, led_rgb->green, arr_size);
++ memcpy(drvdata.led_rgb_data.blue, led_rgb->blue, arr_size);
++
++ ally_rgb_set_static_from_multi(led_rgb->hdev);
++}
++
++static void ally_rgb_restore_settings(struct ally_rgb_dev *led_rgb, struct led_classdev *led_cdev,
++ struct mc_subled *mc_led_info)
++{
++ int arr_size = sizeof(drvdata.led_rgb_data.red);
++
++ memcpy(led_rgb->red, drvdata.led_rgb_data.red, arr_size);
++ memcpy(led_rgb->green, drvdata.led_rgb_data.green, arr_size);
++ memcpy(led_rgb->blue, drvdata.led_rgb_data.blue, arr_size);
++ for (int i = 0; i < 4; i++) {
++ mc_led_info[i].intensity = (drvdata.led_rgb_data.red[i] << 16) |
++ (drvdata.led_rgb_data.green[i] << 8) |
++ drvdata.led_rgb_data.blue[i];
++ }
++ led_cdev->brightness = drvdata.led_rgb_data.brightness;
++}
++
++/* Set LEDs. Call after any setup. */
++static void ally_rgb_resume(void)
++{
++ struct ally_rgb_dev *led_rgb = drvdata.led_rgb_dev;
++ struct led_classdev *led_cdev;
++ struct mc_subled *mc_led_info;
++
++ if (!led_rgb)
++ return;
++
++ led_cdev = &led_rgb->led_rgb_dev.led_cdev;
++ mc_led_info = led_rgb->led_rgb_dev.subled_info;
++
++ if (drvdata.led_rgb_data.initialized) {
++ ally_rgb_restore_settings(led_rgb, led_cdev, mc_led_info);
++ led_rgb->update_rgb = true;
++ ally_rgb_schedule_work(led_rgb);
++ ally_rgb_set_bright_base_max(led_rgb->hdev);
++ }
++}
++
++static int ally_rgb_register(struct hid_device *hdev, struct ally_rgb_dev *led_rgb)
++{
++ struct mc_subled *mc_led_info;
++ struct led_classdev *led_cdev;
++
++ mc_led_info =
++ devm_kmalloc_array(&hdev->dev, 12, sizeof(*mc_led_info), GFP_KERNEL | __GFP_ZERO);
++ if (!mc_led_info)
++ return -ENOMEM;
++
++ mc_led_info[0].color_index = LED_COLOR_ID_RGB;
++ mc_led_info[1].color_index = LED_COLOR_ID_RGB;
++ mc_led_info[2].color_index = LED_COLOR_ID_RGB;
++ mc_led_info[3].color_index = LED_COLOR_ID_RGB;
++
++ led_rgb->led_rgb_dev.subled_info = mc_led_info;
++ led_rgb->led_rgb_dev.num_colors = 4;
++
++ led_cdev = &led_rgb->led_rgb_dev.led_cdev;
++ led_cdev->brightness = 128;
++ led_cdev->name = "ally:rgb:joystick_rings";
++ led_cdev->max_brightness = 255;
++ led_cdev->brightness_set = ally_rgb_set;
++
++ if (drvdata.led_rgb_data.initialized) {
++ ally_rgb_restore_settings(led_rgb, led_cdev, mc_led_info);
++ }
++
++ return devm_led_classdev_multicolor_register(&hdev->dev, &led_rgb->led_rgb_dev);
++}
++
++static struct ally_rgb_dev *ally_rgb_create(struct hid_device *hdev)
++{
++ struct ally_rgb_dev *led_rgb;
++ int ret;
++
++ led_rgb = devm_kzalloc(&hdev->dev, sizeof(struct ally_rgb_dev), GFP_KERNEL);
++ if (!led_rgb)
++ return ERR_PTR(-ENOMEM);
++
++ ret = ally_rgb_register(hdev, led_rgb);
++ if (ret < 0) {
++ cancel_work_sync(&led_rgb->work);
++ devm_kfree(&hdev->dev, led_rgb);
++ return ERR_PTR(ret);
++ }
++
++ led_rgb->hdev = hdev;
++ led_rgb->removed = false;
++
++ INIT_WORK(&led_rgb->work, ally_rgb_do_work);
++ led_rgb->output_worker_initialized = true;
++ spin_lock_init(&led_rgb->lock);
++
++ ally_rgb_set_bright_base_max(hdev);
++
++ /* Not marked as initialized unless ally_rgb_set() is called */
++ if (drvdata.led_rgb_data.initialized) {
++ msleep(1500);
++ led_rgb->update_rgb = true;
++ ally_rgb_schedule_work(led_rgb);
++ }
++
++ return led_rgb;
++}
++
++static void ally_rgb_remove(struct hid_device *hdev)
++{
++ struct ally_rgb_dev *led_rgb = drvdata.led_rgb_dev;
++ unsigned long flags;
++ int ep;
++
++ ep = get_endpoint_address(hdev);
++ if (ep != ALLY_CFG_INTF_IN_ADDRESS)
++ return;
++
++ if (!drvdata.led_rgb_dev || led_rgb->removed)
++ return;
++
++ spin_lock_irqsave(&led_rgb->lock, flags);
++ led_rgb->removed = true;
++ led_rgb->output_worker_initialized = false;
++ spin_unlock_irqrestore(&led_rgb->lock, flags);
++ cancel_work_sync(&led_rgb->work);
++ devm_led_classdev_multicolor_unregister(&hdev->dev, &led_rgb->led_rgb_dev);
++
++ hid_info(hdev, "Removed Ally RGB interface");
++}
++
++/**************************************************************************************************/
++/* ROG Ally driver init */
++/**************************************************************************************************/
++
++/*
++ * Very simple parse. We don't care about any other part of the string except the version section.
++ * Example strings: FGA80100.RC72LA.312_T01, FGA80100.RC71LS.318_T01
++ */
++static int mcu_parse_version_string(const u8 *response, size_t response_size)
++{
++ int dot_count = 0;
++ size_t i;
++
++ // Look for the second '.' to identify the start of the version
++ for (i = 0; i < response_size; i++) {
++ if (response[i] == '.') {
++ dot_count++;
++ if (dot_count == 2) {
++ int version =
++ simple_strtol((const char *)&response[i + 1], NULL, 10);
++ return (version >= 0) ? version : -EINVAL;
++ }
++ }
++ }
++
++ return -EINVAL;
++}
++
++static int mcu_request_version(struct hid_device *hdev)
++{
++ const u8 request[] = { 0x5a, 0x05, 0x03, 0x31, 0x00, 0x20 };
++ size_t response_size = FEATURE_ROG_ALLY_REPORT_SIZE;
++ u8 *response;
++ int ret;
++
++ response = kzalloc(response_size, GFP_KERNEL);
++ if (!response) {
++ kfree(request);
++ return -ENOMEM;
++ }
++
++ ret = asus_dev_set_report(hdev, request, sizeof(request));
++ if (ret < 0)
++ goto error;
++
++ ret = asus_dev_get_report(hdev, response, response_size);
++ if (ret < 0)
++ goto error;
++
++ ret = mcu_parse_version_string(response, response_size);
++ if (ret < 0)
++ goto error;
++
++ goto cleanup;
++
++error:
++ hid_err(hdev, "Failed to get MCU version: %d\n", ret);
++cleanup:
++ kfree(response);
++
++ return ret;
++}
++
++static void mcu_maybe_warn_version(struct hid_device *hdev, int idProduct)
++{
++ int min_version, version;
++
++ min_version = 0;
++ version = mcu_request_version(hdev);
++ if (version) {
++ switch (idProduct) {
++ case USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY:
++ min_version = ALLY_MIN_BIOS;
++ break;
++ case USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X:
++ min_version = ALLY_X_MIN_BIOS;
++ break;
++ }
++ }
++
++ hid_info(hdev, "Ally device MCU version: %d\n", version);
++ if (version <= min_version) {
++ hid_warn(hdev,
++ "The MCU version must be %d or greater\n"
++ "Please update your MCU with official ASUS firmware release "
++ "which has bug fixes to make the Linux experience better\n",
++ min_version);
++ }
++}
++
++static int ally_hid_init(struct hid_device *hdev)
++{
++ int ret;
++
++ ret = asus_dev_set_report(hdev, EC_INIT_STRING, sizeof(EC_INIT_STRING));
++ if (ret < 0) {
++ hid_err(hdev, "Ally failed to send init command: %d\n", ret);
++ return ret;
++ }
++
++ ret = asus_dev_set_report(hdev, FORCE_FEEDBACK_OFF, sizeof(FORCE_FEEDBACK_OFF));
++ if (ret < 0)
++ hid_err(hdev, "Ally failed to send init command: %d\n", ret);
++
++ return ret;
++}
++
++static int ally_hid_probe(struct hid_device *hdev, const struct hid_device_id *_id)
++{
++ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
++ struct usb_device *udev = interface_to_usbdev(intf);
++ u16 idProduct = le16_to_cpu(udev->descriptor.idProduct);
++ int ret, ep;
++
++ ep = get_endpoint_address(hdev);
++ if (ep < 0)
++ return ep;
++
++ if (ep != ALLY_CFG_INTF_IN_ADDRESS)
++ return -ENODEV;
++
++ ret = hid_parse(hdev);
++ if (ret) {
++ hid_err(hdev, "Parse failed\n");
++ return ret;
++ }
++
++ ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
++ if (ret) {
++ hid_err(hdev, "Failed to start HID device\n");
++ return ret;
++ }
++
++ ret = hid_hw_open(hdev);
++ if (ret) {
++ hid_err(hdev, "Failed to open HID device\n");
++ goto err_stop;
++ }
++
++ /* Initialize MCU even before alloc */
++ ret = ally_hid_init(hdev);
++ if (ret < 0)
++ return ret;
++
++ drvdata.hdev = hdev;
++ hid_set_drvdata(hdev, &drvdata);
++
++ /* This should almost always exist */
++ if (ep == ALLY_CFG_INTF_IN_ADDRESS) {
++ mcu_maybe_warn_version(hdev, idProduct);
++
++ drvdata.led_rgb_dev = ally_rgb_create(hdev);
++ if (IS_ERR(drvdata.led_rgb_dev))
++ hid_err(hdev, "Failed to create Ally gamepad LEDs.\n");
++ else
++ hid_info(hdev, "Created Ally RGB LED controls.\n");
++
++ if (IS_ERR(drvdata.led_rgb_dev))
++ goto err_close;
++ }
++
++ return 0;
++
++err_close:
++ hid_hw_close(hdev);
++err_stop:
++ hid_hw_stop(hdev);
++ return ret;
++}
++
++static void ally_hid_remove(struct hid_device *hdev)
++{
++ if (drvdata.led_rgb_dev)
++ ally_rgb_remove(hdev);
++
++ hid_hw_close(hdev);
++ hid_hw_stop(hdev);
++}
++
++static int ally_hid_resume(struct hid_device *hdev)
++{
++ ally_rgb_resume();
++
++ return 0;
++}
++
++static int ally_hid_reset_resume(struct hid_device *hdev)
++{
++ int ep = get_endpoint_address(hdev);
++ if (ep != ALLY_CFG_INTF_IN_ADDRESS)
++ return 0;
++
++ ally_hid_init(hdev);
++ ally_rgb_resume();
++
++ return 0;
++}
++
++static int ally_pm_thaw(struct device *dev)
++{
++ struct hid_device *hdev = to_hid_device(dev);
++
++ return ally_hid_reset_resume(hdev);
++}
++
++static int ally_pm_suspend(struct device *dev)
++{
++ if (drvdata.led_rgb_dev) {
++ ally_rgb_store_settings();
++ }
++
++ return 0;
++}
++
++static const struct dev_pm_ops ally_pm_ops = {
++ .thaw = ally_pm_thaw,
++ .suspend = ally_pm_suspend,
++ .poweroff = ally_pm_suspend,
++};
++
++MODULE_DEVICE_TABLE(hid, rog_ally_devices);
++
++static struct hid_driver
++ rog_ally_cfg = { .name = "asus_rog_ally",
++ .id_table = rog_ally_devices,
++ .probe = ally_hid_probe,
++ .remove = ally_hid_remove,
++ /* HID is the better place for resume functions, not pm_ops */
++ .resume = ally_hid_resume,
++ .reset_resume = ally_hid_reset_resume,
++ .driver = {
++ .pm = &ally_pm_ops,
++ } };
++
++static int __init rog_ally_init(void)
++{
++ return hid_register_driver(&rog_ally_cfg);
++}
++
++static void __exit rog_ally_exit(void)
++{
++ hid_unregister_driver(&rog_ally_cfg);
++}
++
++module_init(rog_ally_init);
++module_exit(rog_ally_exit);
++
++MODULE_AUTHOR("Luke D. Jones");
++MODULE_DESCRIPTION("HID Driver for ASUS ROG Ally gamepad configuration.");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+new file mode 100644
+index 000000000000..eb8617c80c2a
+--- /dev/null
++++ b/drivers/hid/hid-asus-ally.h
+@@ -0,0 +1,38 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later
++ *
++ * HID driver for Asus ROG laptops and Ally
++ *
++ * Copyright (c) 2023 Luke Jones
++ */
++
++#include
++#include
++
++/* the xpad_cmd determines which feature is set or queried */
++enum xpad_cmd {
++ xpad_cmd_set_mode = 0x01,
++ xpad_cmd_set_mapping = 0x02,
++ xpad_cmd_set_js_dz = 0x04, /* deadzones */
++ xpad_cmd_set_tr_dz = 0x05, /* deadzones */
++ xpad_cmd_set_vibe_intensity = 0x06,
++ xpad_cmd_set_leds = 0x08,
++ xpad_cmd_check_ready = 0x0A,
++ xpad_cmd_set_calibration = 0x0D,
++ xpad_cmd_set_turbo = 0x0F,
++ xpad_cmd_set_response_curve = 0x13,
++ xpad_cmd_set_adz = 0x18,
++};
++
++/* the xpad_cmd determines which feature is set or queried */
++enum xpad_cmd_len {
++ xpad_cmd_len_mode = 0x01,
++ xpad_cmd_len_mapping = 0x2c,
++ xpad_cmd_len_deadzone = 0x04,
++ xpad_cmd_len_vibe_intensity = 0x02,
++ xpad_cmd_len_leds = 0x0C,
++ xpad_cmd_len_calibration2 = 0x01,
++ xpad_cmd_len_calibration3 = 0x01,
++ xpad_cmd_len_turbo = 0x20,
++ xpad_cmd_len_response_curve = 0x09,
++ xpad_cmd_len_adz = 0x02,
++};
+diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
+index 9540e3e19cce..7c5269cd4d76 100644
+--- a/drivers/hid/hid-asus.c
++++ b/drivers/hid/hid-asus.c
+@@ -52,6 +52,10 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
+ #define FEATURE_KBD_LED_REPORT_ID1 0x5d
+ #define FEATURE_KBD_LED_REPORT_ID2 0x5e
+
++#define ALLY_CFG_INTF_IN_ADDRESS 0x83
++#define ALLY_CFG_INTF_OUT_ADDRESS 0x04
++#define ALLY_X_INTERFACE_ADDRESS 0x87
++
+ #define SUPPORT_KBD_BACKLIGHT BIT(0)
+
+ #define MAX_TOUCH_MAJOR 8
+@@ -84,6 +88,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
+ #define QUIRK_MEDION_E1239T BIT(10)
+ #define QUIRK_ROG_NKEY_KEYBOARD BIT(11)
+ #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
++#define QUIRK_ROG_ALLY_XPAD BIT(13)
+
+ #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
+ QUIRK_NO_INIT_REPORTS | \
+@@ -1003,6 +1008,17 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
+
+ drvdata->quirks = id->driver_data;
+
++ /* Ignore these endpoints as they will be used by other drivers */
++ if (drvdata->quirks & QUIRK_ROG_ALLY_XPAD) {
++ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
++ struct usb_host_endpoint *ep = intf->cur_altsetting->endpoint;
++
++ if (ep->desc.bEndpointAddress == ALLY_X_INTERFACE_ADDRESS ||
++ ep->desc.bEndpointAddress == ALLY_CFG_INTF_IN_ADDRESS ||
++ ep->desc.bEndpointAddress == ALLY_CFG_INTF_OUT_ADDRESS)
++ return -ENODEV;
++ }
++
+ /*
+ * T90CHI's keyboard dock returns same ID values as T100CHI's dock.
+ * Thus, identify T90CHI dock with product name string.
+@@ -1254,10 +1270,10 @@ static const struct hid_device_id asus_devices[] = {
+ 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 },
++ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD},
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+ USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
+- QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
++ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+ USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
+ QUIRK_ROG_CLAYMORE_II_KEYBOARD },
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0015-hid-asus-ally-initial-Ally-X-gamepad.patch b/packages/l/linux-current/files/patches/hardware/asus/0015-hid-asus-ally-initial-Ally-X-gamepad.patch
new file mode 100644
index 00000000000..62fa0435c68
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0015-hid-asus-ally-initial-Ally-X-gamepad.patch
@@ -0,0 +1,483 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Wed, 2 Oct 2024 23:32:46 +1300
+Subject: [PATCH 15/27] hid-asus-ally: initial Ally-X gamepad
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 399 +++++++++++++++++++++++++++++++++++-
+ drivers/hid/hid-asus-ally.h | 5 +
+ 2 files changed, 403 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index bfadf5cd700d..33d9ac0c6bd5 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -49,6 +49,51 @@ static const struct hid_device_id rog_ally_devices[] = {
+ {}
+ };
+
++/* The hatswitch outputs integers, we use them to index this X|Y pair */
++static const int hat_values[][2] = {
++ { 0, 0 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
++ { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 },
++};
++
++/* rumble packet structure */
++struct ff_data {
++ u8 enable;
++ u8 magnitude_left;
++ u8 magnitude_right;
++ u8 magnitude_strong;
++ u8 magnitude_weak;
++ u8 pulse_sustain_10ms;
++ u8 pulse_release_10ms;
++ u8 loop_count;
++} __packed;
++
++struct ff_report {
++ u8 report_id;
++ struct ff_data ff;
++} __packed;
++
++struct ally_x_input_report {
++ uint16_t x, y;
++ uint16_t rx, ry;
++ uint16_t z, rz;
++ uint8_t buttons[4];
++} __packed;
++
++struct ally_x_device {
++ struct input_dev *input;
++ struct hid_device *hdev;
++ spinlock_t lock;
++
++ struct ff_report *ff_packet;
++ struct work_struct output_worker;
++ bool output_worker_initialized;
++ /* Prevent multiple queued event due to the enforced delay in worker */
++ bool update_qam_btn;
++ /* Set if the QAM and AC buttons emit Xbox and Xbox+A */
++ bool qam_btns_steam_mode;
++ bool update_ff;
++};
++
+ struct ally_rgb_dev {
+ struct hid_device *hdev;
+ struct led_classdev_mc led_rgb_dev;
+@@ -73,6 +118,7 @@ struct ally_rgb_data {
+
+ static struct ally_drvdata {
+ struct hid_device *hdev;
++ struct ally_x_device *ally_x;
+ struct ally_rgb_dev *led_rgb_dev;
+ struct ally_rgb_data led_rgb_data;
+ } drvdata;
+@@ -127,6 +173,309 @@ static u8 get_endpoint_address(struct hid_device *hdev)
+ return -ENODEV;
+ }
+
++/**************************************************************************************************/
++/* ROG Ally gamepad i/o and force-feedback */
++/**************************************************************************************************/
++static int ally_x_raw_event(struct ally_x_device *ally_x, struct hid_report *report, u8 *data,
++ int size)
++{
++ struct ally_x_input_report *in_report;
++ unsigned long flags;
++ u8 byte;
++
++ if (data[0] == 0x0B) {
++ in_report = (struct ally_x_input_report *)&data[1];
++
++ input_report_abs(ally_x->input, ABS_X, in_report->x);
++ input_report_abs(ally_x->input, ABS_Y, in_report->y);
++ input_report_abs(ally_x->input, ABS_RX, in_report->rx);
++ input_report_abs(ally_x->input, ABS_RY, in_report->ry);
++ input_report_abs(ally_x->input, ABS_Z, in_report->z);
++ input_report_abs(ally_x->input, ABS_RZ, in_report->rz);
++
++ byte = in_report->buttons[0];
++ input_report_key(ally_x->input, BTN_A, byte & BIT(0));
++ input_report_key(ally_x->input, BTN_B, byte & BIT(1));
++ input_report_key(ally_x->input, BTN_X, byte & BIT(2));
++ input_report_key(ally_x->input, BTN_Y, byte & BIT(3));
++ input_report_key(ally_x->input, BTN_TL, byte & BIT(4));
++ input_report_key(ally_x->input, BTN_TR, byte & BIT(5));
++ input_report_key(ally_x->input, BTN_SELECT, byte & BIT(6));
++ input_report_key(ally_x->input, BTN_START, byte & BIT(7));
++
++ byte = in_report->buttons[1];
++ input_report_key(ally_x->input, BTN_THUMBL, byte & BIT(0));
++ input_report_key(ally_x->input, BTN_THUMBR, byte & BIT(1));
++ input_report_key(ally_x->input, BTN_MODE, byte & BIT(2));
++
++ byte = in_report->buttons[2];
++ input_report_abs(ally_x->input, ABS_HAT0X, hat_values[byte][0]);
++ input_report_abs(ally_x->input, ABS_HAT0Y, hat_values[byte][1]);
++ }
++ /*
++ * The MCU used on Ally provides many devices: gamepad, keyboord, mouse, other.
++ * The AC and QAM buttons route through another interface making it difficult to
++ * use the events unless we grab those and use them here. Only works for Ally X.
++ */
++ else if (data[0] == 0x5A) {
++ if (ally_x->qam_btns_steam_mode) {
++ spin_lock_irqsave(&ally_x->lock, flags);
++ if (data[1] == 0x38 && !ally_x->update_qam_btn) {
++ ally_x->update_qam_btn = true;
++ if (ally_x->output_worker_initialized)
++ schedule_work(&ally_x->output_worker);
++ }
++ spin_unlock_irqrestore(&ally_x->lock, flags);
++ /* Left/XBox button. Long press does ctrl+alt+del which we can't catch */
++ input_report_key(ally_x->input, BTN_MODE, data[1] == 0xA6);
++ } else {
++ input_report_key(ally_x->input, KEY_F16, data[1] == 0xA6);
++ input_report_key(ally_x->input, KEY_PROG1, data[1] == 0x38);
++ }
++ /* QAM long press */
++ input_report_key(ally_x->input, KEY_F17, data[1] == 0xA7);
++ /* QAM long press released */
++ input_report_key(ally_x->input, KEY_F18, data[1] == 0xA8);
++ }
++
++ input_sync(ally_x->input);
++
++ return 0;
++}
++
++static struct input_dev *ally_x_alloc_input_dev(struct hid_device *hdev,
++ const char *name_suffix)
++{
++ struct input_dev *input_dev;
++
++ input_dev = devm_input_allocate_device(&hdev->dev);
++ if (!input_dev)
++ return ERR_PTR(-ENOMEM);
++
++ input_dev->id.bustype = hdev->bus;
++ input_dev->id.vendor = hdev->vendor;
++ input_dev->id.product = hdev->product;
++ input_dev->id.version = hdev->version;
++ input_dev->uniq = hdev->uniq;
++ input_dev->name = "ASUS ROG Ally X Gamepad";
++
++ input_set_drvdata(input_dev, hdev);
++
++ return input_dev;
++}
++
++static int ally_x_play_effect(struct input_dev *idev, void *data, struct ff_effect *effect)
++{
++ struct ally_x_device *ally_x = drvdata.ally_x;
++ unsigned long flags;
++
++ if (effect->type != FF_RUMBLE)
++ return 0;
++
++ spin_lock_irqsave(&ally_x->lock, flags);
++ ally_x->ff_packet->ff.magnitude_strong = effect->u.rumble.strong_magnitude / 512;
++ ally_x->ff_packet->ff.magnitude_weak = effect->u.rumble.weak_magnitude / 512;
++ ally_x->update_ff = true;
++ spin_unlock_irqrestore(&ally_x->lock, flags);
++
++ if (ally_x->output_worker_initialized)
++ schedule_work(&ally_x->output_worker);
++
++ return 0;
++}
++
++static void ally_x_work(struct work_struct *work)
++{
++ struct ally_x_device *ally_x = container_of(work, struct ally_x_device, output_worker);
++ struct ff_report *ff_report = NULL;
++ bool update_qam = false;
++ bool update_ff = false;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ally_x->lock, flags);
++ update_ff = ally_x->update_ff;
++ if (ally_x->update_ff) {
++ ff_report = kmemdup(ally_x->ff_packet, sizeof(*ally_x->ff_packet), GFP_KERNEL);
++ ally_x->update_ff = false;
++ }
++ update_qam = ally_x->update_qam_btn;
++ spin_unlock_irqrestore(&ally_x->lock, flags);
++
++ if (update_ff && ff_report) {
++ ff_report->ff.magnitude_left = ff_report->ff.magnitude_strong;
++ ff_report->ff.magnitude_right = ff_report->ff.magnitude_weak;
++ asus_dev_set_report(ally_x->hdev, (u8 *)ff_report, sizeof(*ff_report));
++ }
++ kfree(ff_report);
++
++ if (update_qam) {
++ /*
++ * The sleeps here are required to allow steam to register the button combo.
++ */
++ usleep_range(1000, 2000);
++ input_report_key(ally_x->input, BTN_MODE, 1);
++ input_sync(ally_x->input);
++
++ msleep(80);
++ input_report_key(ally_x->input, BTN_A, 1);
++ input_sync(ally_x->input);
++
++ msleep(80);
++ input_report_key(ally_x->input, BTN_A, 0);
++ input_sync(ally_x->input);
++
++ msleep(80);
++ input_report_key(ally_x->input, BTN_MODE, 0);
++ input_sync(ally_x->input);
++
++ spin_lock_irqsave(&ally_x->lock, flags);
++ ally_x->update_qam_btn = false;
++ spin_unlock_irqrestore(&ally_x->lock, flags);
++ }
++}
++
++static struct input_dev *ally_x_setup_input(struct hid_device *hdev)
++{
++ int ret, abs_min = 0, js_abs_max = 65535, tr_abs_max = 1023;
++ struct input_dev *input;
++
++ input = ally_x_alloc_input_dev(hdev, NULL);
++ if (IS_ERR(input))
++ return ERR_CAST(input);
++
++ input_set_abs_params(input, ABS_X, abs_min, js_abs_max, 0, 0);
++ input_set_abs_params(input, ABS_Y, abs_min, js_abs_max, 0, 0);
++ input_set_abs_params(input, ABS_RX, abs_min, js_abs_max, 0, 0);
++ input_set_abs_params(input, ABS_RY, abs_min, js_abs_max, 0, 0);
++ input_set_abs_params(input, ABS_Z, abs_min, tr_abs_max, 0, 0);
++ input_set_abs_params(input, ABS_RZ, abs_min, tr_abs_max, 0, 0);
++ input_set_abs_params(input, ABS_HAT0X, -1, 1, 0, 0);
++ input_set_abs_params(input, ABS_HAT0Y, -1, 1, 0, 0);
++ input_set_capability(input, EV_KEY, BTN_A);
++ input_set_capability(input, EV_KEY, BTN_B);
++ input_set_capability(input, EV_KEY, BTN_X);
++ input_set_capability(input, EV_KEY, BTN_Y);
++ input_set_capability(input, EV_KEY, BTN_TL);
++ input_set_capability(input, EV_KEY, BTN_TR);
++ input_set_capability(input, EV_KEY, BTN_SELECT);
++ input_set_capability(input, EV_KEY, BTN_START);
++ input_set_capability(input, EV_KEY, BTN_MODE);
++ input_set_capability(input, EV_KEY, BTN_THUMBL);
++ input_set_capability(input, EV_KEY, BTN_THUMBR);
++
++ input_set_capability(input, EV_KEY, KEY_PROG1);
++ input_set_capability(input, EV_KEY, KEY_F16);
++ input_set_capability(input, EV_KEY, KEY_F17);
++ input_set_capability(input, EV_KEY, KEY_F18);
++
++ input_set_capability(input, EV_FF, FF_RUMBLE);
++ input_ff_create_memless(input, NULL, ally_x_play_effect);
++
++ ret = input_register_device(input);
++ if (ret)
++ return ERR_PTR(ret);
++
++ return input;
++}
++
++static ssize_t ally_x_qam_mode_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct ally_x_device *ally_x = drvdata.ally_x;
++
++ return sysfs_emit(buf, "%d\n", ally_x->qam_btns_steam_mode);
++}
++
++static ssize_t ally_x_qam_mode_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct ally_x_device *ally_x = drvdata.ally_x;
++ bool val;
++ int ret;
++
++ ret = kstrtobool(buf, &val);
++ if (ret < 0)
++ return ret;
++
++ ally_x->qam_btns_steam_mode = val;
++
++ return count;
++}
++ALLY_DEVICE_ATTR_RW(ally_x_qam_mode, qam_mode);
++
++static struct ally_x_device *ally_x_create(struct hid_device *hdev)
++{
++ uint8_t max_output_report_size;
++ struct ally_x_device *ally_x;
++ struct ff_report *report;
++ int ret;
++
++ ally_x = devm_kzalloc(&hdev->dev, sizeof(*ally_x), GFP_KERNEL);
++ if (!ally_x)
++ return ERR_PTR(-ENOMEM);
++
++ ally_x->hdev = hdev;
++ INIT_WORK(&ally_x->output_worker, ally_x_work);
++ spin_lock_init(&ally_x->lock);
++ ally_x->output_worker_initialized = true;
++ ally_x->qam_btns_steam_mode =
++ true; /* Always default to steam mode, it can be changed by userspace attr */
++
++ max_output_report_size = sizeof(struct ally_x_input_report);
++ report = devm_kzalloc(&hdev->dev, sizeof(*report), GFP_KERNEL);
++ if (!report) {
++ ret = -ENOMEM;
++ goto free_ally_x;
++ }
++
++ /* None of these bytes will change for the FF command for now */
++ report->report_id = 0x0D;
++ report->ff.enable = 0x0F; /* Enable all by default */
++ report->ff.pulse_sustain_10ms = 0xFF; /* Duration */
++ report->ff.pulse_release_10ms = 0x00; /* Start Delay */
++ report->ff.loop_count = 0xEB; /* Loop Count */
++ ally_x->ff_packet = report;
++
++ ally_x->input = ally_x_setup_input(hdev);
++ if (IS_ERR(ally_x->input)) {
++ ret = PTR_ERR(ally_x->input);
++ goto free_ff_packet;
++ }
++
++ if (sysfs_create_file(&hdev->dev.kobj, &dev_attr_ally_x_qam_mode.attr)) {
++ ret = -ENODEV;
++ goto unregister_input;
++ }
++
++ ally_x->update_ff = true;
++ if (ally_x->output_worker_initialized)
++ schedule_work(&ally_x->output_worker);
++
++ hid_info(hdev, "Registered Ally X controller using %s\n",
++ dev_name(&ally_x->input->dev));
++ return ally_x;
++
++unregister_input:
++ input_unregister_device(ally_x->input);
++free_ff_packet:
++ kfree(ally_x->ff_packet);
++free_ally_x:
++ kfree(ally_x);
++ return ERR_PTR(ret);
++}
++
++static void ally_x_remove(struct hid_device *hdev)
++{
++ struct ally_x_device *ally_x = drvdata.ally_x;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ally_x->lock, flags);
++ ally_x->output_worker_initialized = false;
++ spin_unlock_irqrestore(&ally_x->lock, flags);
++ cancel_work_sync(&ally_x->output_worker);
++ sysfs_remove_file(&hdev->dev.kobj, &dev_attr_ally_x_qam_mode.attr);
++}
++
+ /**************************************************************************************************/
+ /* ROG Ally LED control */
+ /**************************************************************************************************/
+@@ -377,6 +726,32 @@ static void ally_rgb_remove(struct hid_device *hdev)
+ /* ROG Ally driver init */
+ /**************************************************************************************************/
+
++static int ally_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data,
++ int size)
++{
++ // struct ally_gamepad_cfg *cfg = drvdata.gamepad_cfg;
++ struct ally_x_device *ally_x = drvdata.ally_x;
++
++ if (ally_x) {
++ if ((hdev->bus == BUS_USB && report->id == ALLY_X_INPUT_REPORT_USB &&
++ size == ALLY_X_INPUT_REPORT_USB_SIZE) ||
++ (data[0] == 0x5A)) {
++ ally_x_raw_event(ally_x, report, data, size);
++ } else {
++ return -1;
++ }
++ }
++ // if (cfg && !ally_x) {
++ // input_report_key(cfg->input, KEY_PROG1, data[1] == 0x38);
++ // input_report_key(cfg->input, KEY_F16, data[1] == 0xA6);
++ // input_report_key(cfg->input, KEY_F17, data[1] == 0xA7);
++ // input_report_key(cfg->input, KEY_F18, data[1] == 0xA8);
++ // input_sync(cfg->input);
++ // }
++
++ return 0;
++}
++
+ /*
+ * Very simple parse. We don't care about any other part of the string except the version section.
+ * Example strings: FGA80100.RC72LA.312_T01, FGA80100.RC71LS.318_T01
+@@ -491,7 +866,8 @@ static int ally_hid_probe(struct hid_device *hdev, const struct hid_device_id *_
+ if (ep < 0)
+ return ep;
+
+- if (ep != ALLY_CFG_INTF_IN_ADDRESS)
++ if (ep != ALLY_CFG_INTF_IN_ADDRESS ||
++ ep != ALLY_X_INTERFACE_ADDRESS)
+ return -ENODEV;
+
+ ret = hid_parse(hdev);
+@@ -534,6 +910,23 @@ static int ally_hid_probe(struct hid_device *hdev, const struct hid_device_id *_
+ goto err_close;
+ }
+
++ /* May or may not exist */
++ if (ep == ALLY_X_INTERFACE_ADDRESS) {
++ drvdata.ally_x = ally_x_create(hdev);
++ if (IS_ERR(drvdata.ally_x)) {
++ hid_err(hdev, "Failed to create Ally X gamepad.\n");
++ drvdata.ally_x = NULL;
++ goto err_close;
++ }
++ hid_info(hdev, "Created Ally X controller.\n");
++
++ // Not required since we send this inputs ep through the gamepad input dev
++ // if (drvdata.gamepad_cfg && drvdata.gamepad_cfg->input) {
++ // input_unregister_device(drvdata.gamepad_cfg->input);
++ // hid_info(hdev, "Ally X removed unrequired input dev.\n");
++ // }
++ }
++
+ return 0;
+
+ err_close:
+@@ -548,6 +941,9 @@ static void ally_hid_remove(struct hid_device *hdev)
+ if (drvdata.led_rgb_dev)
+ ally_rgb_remove(hdev);
+
++ if (drvdata.ally_x)
++ ally_x_remove(hdev);
++
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+ }
+@@ -600,6 +996,7 @@ static struct hid_driver
+ .id_table = rog_ally_devices,
+ .probe = ally_hid_probe,
+ .remove = ally_hid_remove,
++ .raw_event = ally_raw_event,
+ /* HID is the better place for resume functions, not pm_ops */
+ .resume = ally_hid_resume,
+ .reset_resume = ally_hid_reset_resume,
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index eb8617c80c2a..458d02996bca 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -36,3 +36,8 @@ enum xpad_cmd_len {
+ xpad_cmd_len_response_curve = 0x09,
+ xpad_cmd_len_adz = 0x02,
+ };
++
++/* required so we can have nested attributes with same name but different functions */
++#define ALLY_DEVICE_ATTR_RW(_name, _sysfs_name) \
++ struct device_attribute dev_attr_##_name = \
++ __ATTR(_sysfs_name, 0644, _name##_show, _name##_store)
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0016-hid-asus-ally-Add-full-gamepad-support.patch b/packages/l/linux-current/files/patches/hardware/asus/0016-hid-asus-ally-Add-full-gamepad-support.patch
deleted file mode 100644
index e2e3c0b6be8..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0016-hid-asus-ally-Add-full-gamepad-support.patch
+++ /dev/null
@@ -1,3033 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones"
-Date: Mon, 26 Aug 2024 12:49:35 +1200
-Subject: [PATCH 16/18] hid-asus-ally: Add full gamepad support
-
-This driver adds full support of the ASUS ROG Ally gamepad:
-
-- dinput is translated to XBox controller (Ally-X only)
-- default mode has the QAM buttons mapped (Ally-X only)
- * left is XBox button
- * right is an XBox + A combo for steam QAM
-- force feedback is supported (Ally-X only)
-- LED brightness control (0-2)
-- LED multicolor class support for all 4 LED, individually addressable
-- Support all configuration
-
-Where "Ally-X only" is mentioned, this is because the Ally 1 uses the
-existing xpad driver.
-
-The configuration options available are:
-
-- Gamepad mode (game, wasd, mouse)
-- Remapping each button, plus macro map (hold a macro button and press other)
-- Joystrick and trigger deadzones
-- Gamepad vibration intensity
-- Leds (using multicolor class)
-- Button turbo abilities (per button)
-- Joystick repsonse curves
-- Joystick anti-deadzones
-
-The attribute path tree looks like this:
-
-- `./sys/..//`
- - `joystick_left/
- - `deadzone`
- - `mapping` (mouse, wasd, custom)
- - `anti_deadzone`
- - `response_curve`
- - `calibration`
- - `calibration_reset`
- - `trigger_left/
- - `deadzone`
- - `response_curve`
- - `calibration`
- - `calibration_reset`
- - `gamepad_mode`
- - `button_mapping`
- - `A`
- - `B`
- - `dpad_left`
- - etc
-
-No settings are applied until `apply_all` is written to. The exception is
-for calibrations.
-
-While there is calibration ability, it can be difficult to get correct
-and is heavily device dependent, as such it is set when written and not
-when `apply_all` is written to. On driver load the set calibrations are
-retrieved - this may be what you've set in Linux, Windows, or factory
-defaults.
-
-As a note: the proper way to set calibrations is to read the joystick
-voltage from the EC whcih currently is not possible.
-
-Signed-off-by: Luke D. Jones
----
- drivers/hid/Kconfig | 9 +
- drivers/hid/Makefile | 1 +
- drivers/hid/hid-asus-ally.c | 2316 +++++++++++++++++++++++++++++++++++
- drivers/hid/hid-asus-ally.h | 544 ++++++++
- drivers/hid/hid-asus.c | 20 +-
- 5 files changed, 2888 insertions(+), 2 deletions(-)
- create mode 100644 drivers/hid/hid-asus-ally.c
- create mode 100644 drivers/hid/hid-asus-ally.h
-
-diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
-index 08446c89eff6..ea0dbe9111c4 100644
---- a/drivers/hid/Kconfig
-+++ b/drivers/hid/Kconfig
-@@ -164,6 +164,15 @@ config HID_ASUS
- - GL553V series
- - GL753V series
-
-+config HID_ASUS_ALLY
-+ tristate "Asus Ally gamepad configuration support"
-+ depends on USB_HID
-+ depends on LEDS_CLASS
-+ depends on LEDS_CLASS_MULTICOLOR
-+ select POWER_SUPPLY
-+ help
-+ Support for configuring the Asus ROG Ally gamepad using attributes.
-+
- config HID_AUREAL
- tristate "Aureal"
- help
-diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
-index e40f1ddebbb7..2b2aa8b6f828 100644
---- a/drivers/hid/Makefile
-+++ b/drivers/hid/Makefile
-@@ -31,6 +31,7 @@ obj-$(CONFIG_HID_APPLE) += hid-apple.o
- obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o
- obj-$(CONFIG_HID_CREATIVE_SB0540) += hid-creative-sb0540.o
- obj-$(CONFIG_HID_ASUS) += hid-asus.o
-+obj-$(CONFIG_HID_ASUS_ALLY) += hid-asus-ally.o
- obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
- obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
- obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o
-diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
-new file mode 100644
-index 000000000000..42a703c157f5
---- /dev/null
-+++ b/drivers/hid/hid-asus-ally.c
-@@ -0,0 +1,2316 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * HID driver for Asus ROG laptops and Ally
-+ *
-+ * Copyright (c) 2023 Luke Jones
-+ */
-+
-+#include "linux/delay.h"
-+#include "linux/device.h"
-+#include "linux/err.h"
-+#include "linux/input-event-codes.h"
-+#include "linux/kstrtox.h"
-+#include "linux/slab.h"
-+#include "linux/stddef.h"
-+#include "linux/sysfs.h"
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include "hid-ids.h"
-+#include "hid-asus-ally.h"
-+
-+#define READY_MAX_TRIES 3
-+#define FEATURE_REPORT_ID 0x0d
-+#define FEATURE_ROG_ALLY_REPORT_ID 0x5a
-+#define FEATURE_ROG_ALLY_CODE_PAGE 0xD1
-+#define FEATURE_ROG_ALLY_REPORT_SIZE 64
-+#define ALLY_X_INPUT_REPORT_USB 0x0B
-+#define ALLY_X_INPUT_REPORT_USB_SIZE 16
-+
-+#define ALLY_CFG_INTF_IN_ADDRESS 0x83
-+#define ALLY_CFG_INTF_OUT_ADDRESS 0x04
-+#define ALLY_X_INTERFACE_ADDRESS 0x87
-+
-+#define FEATURE_KBD_LED_REPORT_ID1 0x5d
-+#define FEATURE_KBD_LED_REPORT_ID2 0x5e
-+
-+enum ROG_ALLY_TYPE {
-+ ROG_ALLY_TYPE,
-+ ROG_ALLY_TYPE_X,
-+};
-+
-+static const struct hid_device_id rog_ally_devices[] = {
-+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY),
-+ .driver_data = ROG_ALLY_TYPE },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
-+ .driver_data = ROG_ALLY_TYPE_X },
-+ {}
-+};
-+
-+struct KeyCode {
-+ const char *label;
-+ u8 code;
-+};
-+
-+static const struct KeyCode gamepad_codes[] = {
-+ { "PAD_A", 0x01 }, { "PAD_B", 0x02 }, { "PAD_X", 0x03 },
-+ { "PAD_Y", 0x04 }, { "PAD_LB", 0x05 }, { "PAD_RB", 0x06 },
-+ { "PAD_LS", 0x07 }, { "PAD_RS", 0x08 }, { "PAD_DPAD_UP", 0x09 },
-+ { "PAD_DPAD_DOWN", 0x0a }, { "PAD_DPAD_LEFT", 0x0b }, { "PAD_DPAD_RIGHT", 0x0c },
-+ { "PAD_VIEW", 0x11 }, { "PAD_MENU", 0x12 }, { "PAD_XBOX", 0x13 }
-+};
-+
-+static const struct KeyCode keyboard_codes[] = { { "KB_M1", 0x8f },
-+ { "KB_M2", 0x8e },
-+ { "KB_ESC", 0x76 },
-+ { "KB_F1", 0x50 },
-+ { "KB_F2", 0x60 },
-+ { "KB_F3", 0x40 },
-+ { "KB_F4", 0x0c },
-+ { "KB_F5", 0x03 },
-+ { "KB_F6", 0x0b },
-+ { "KB_F7", 0x80 },
-+ { "KB_F8", 0x0a },
-+ { "KB_F9", 0x01 },
-+ { "KB_F10", 0x09 },
-+ { "KB_F11", 0x78 },
-+ { "KB_F12", 0x07 },
-+ { "KB_F14", 0x10 },
-+ { "KB_F15", 0x18 },
-+ { "KB_BACKTICK", 0x0e },
-+ { "KB_1", 0x16 },
-+ { "KB_2", 0x1e },
-+ { "KB_3", 0x26 },
-+ { "KB_4", 0x25 },
-+ { "KB_5", 0x2e },
-+ { "KB_6", 0x36 },
-+ { "KB_7", 0x3d },
-+ { "KB_8", 0x3e },
-+ { "KB_9", 0x46 },
-+ { "KB_0", 0x45 },
-+ { "KB_HYPHEN", 0x4e },
-+ { "KB_EQUALS", 0x55 },
-+ { "KB_BACKSPACE", 0x66 },
-+ { "KB_TAB", 0x0d },
-+ { "KB_Q", 0x15 },
-+ { "KB_W", 0x1d },
-+ { "KB_E", 0x24 },
-+ { "KB_R", 0x2d },
-+ { "KB_T", 0x2d },
-+ { "KB_Y", 0x35 },
-+ { "KB_U", 0x3c },
-+ { "KB_I", 0x43 },
-+ { "KB_O", 0x44 },
-+ { "KB_P", 0x4d },
-+ { "KB_LBRACKET", 0x54 },
-+ { "KB_RBRACKET", 0x5b },
-+ { "KB_BACKSLASH", 0x5d },
-+ { "KB_CAPS", 0x58 },
-+ { "KB_A", 0x1c },
-+ { "KB_S", 0x1b },
-+ { "KB_D", 0x23 },
-+ { "KB_F", 0x2b },
-+ { "KB_G", 0x34 },
-+ { "KB_H", 0x33 },
-+ { "KB_J", 0x3b },
-+ { "KB_K", 0x42 },
-+ { "KB_L", 0x4b },
-+ { "KB_SEMI", 0x4c },
-+ { "KB_QUOTE", 0x52 },
-+ { "KB_RET", 0x5a },
-+ { "KB_LSHIFT", 0x88 },
-+ { "KB_Z", 0x1a },
-+ { "KB_X", 0x22 },
-+ { "KB_C", 0x21 },
-+ { "KB_V", 0x2a },
-+ { "KB_B", 0x32 },
-+ { "KB_N", 0x31 },
-+ { "KB_M", 0x3a },
-+ { "KB_COMMA", 0x41 },
-+ { "KB_PERIOD", 0x49 },
-+ { "KB_FWDSLASH", 0x4a },
-+ { "KB_RSHIFT", 0x89 },
-+ { "KB_LCTL", 0x8c },
-+ { "KB_META", 0x82 },
-+ { "KB_LALT", 0xba },
-+ { "KB_SPACE", 0x29 },
-+ { "KB_RALT", 0x8b },
-+ { "KB_MENU", 0x84 },
-+ { "KB_RCTL", 0x8d },
-+ { "KB_PRNTSCN", 0xc3 },
-+ { "KB_SCRLCK", 0x7e },
-+ { "KB_PAUSE", 0x91 },
-+ { "KB_INS", 0xc2 },
-+ { "KB_HOME", 0x94 },
-+ { "KB_PGUP", 0x96 },
-+ { "KB_DEL", 0xc0 },
-+ { "KB_END", 0x95 },
-+ { "KB_PGDWN", 0x97 },
-+ { "KB_UP_ARROW", 0x99 },
-+ { "KB_DOWN_ARROW", 0x98 },
-+ { "KB_LEFT_ARROW", 0x91 },
-+ { "KB_RIGHT_ARROW", 0x9b },
-+ { "NUMPAD_LOCK", 0x77 },
-+ { "NUMPAD_FWDSLASH", 0x90 },
-+ { "NUMPAD_ASTERISK", 0x7c },
-+ { "NUMPAD_HYPHEN", 0x7b },
-+ { "NUMPAD_0", 0x70 },
-+ { "NUMPAD_1", 0x69 },
-+ { "NUMPAD_2", 0x72 },
-+ { "NUMPAD_3", 0x7a },
-+ { "NUMPAD_4", 0x6b },
-+ { "NUMPAD_5", 0x73 },
-+ { "NUMPAD_6", 0x74 },
-+ { "NUMPAD_7", 0x6c },
-+ { "NUMPAD_8", 0x75 },
-+ { "NUMPAD_9", 0x7d },
-+ { "NUMPAD_PLUS", 0x79 },
-+ { "NUMPAD_ENTER", 0x81 },
-+ { "NUMPAD_PERIOD", 0x71 } };
-+
-+static const struct KeyCode mouse_codes[] = { { "MOUSE_LCLICK", 0x01 },
-+ { "MOUSE_RCLICK", 0x02 },
-+ { "MOUSE_MCLICK", 0x03 },
-+ { "MOUSE_WHEEL_UP", 0x04 },
-+ { "MOUSE_WHEEL_DOWN", 0x05 } };
-+
-+static const struct KeyCode media_codes[] = {
-+ { "MEDIA_SCREENSHOT", 0x16 }, { "MEDIA_SHOW_KEYBOARD", 0x19 },
-+ { "MEDIA_SHOW_DESKTOP", 0x1c }, { "MEDIA_START_RECORDING", 0x1e },
-+ { "MEDIA_MIC_OFF", 0x01 }, { "MEDIA_VOL_DOWN", 0x02 },
-+ { "MEDIA_VOL_UP", 0x03 }
-+};
-+
-+/* The hatswitch outputs integers, we use them to index this X|Y pair */
-+static const int hat_values[][2] = {
-+ { 0, 0 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
-+ { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 },
-+};
-+
-+/* rumble packet structure */
-+struct ff_data {
-+ u8 enable;
-+ u8 magnitude_left;
-+ u8 magnitude_right;
-+ u8 magnitude_strong;
-+ u8 magnitude_weak;
-+ u8 pulse_sustain_10ms;
-+ u8 pulse_release_10ms;
-+ u8 loop_count;
-+} __packed;
-+
-+struct ff_report {
-+ u8 report_id;
-+ struct ff_data ff;
-+} __packed;
-+
-+struct ally_x_input_report {
-+ uint16_t x, y;
-+ uint16_t rx, ry;
-+ uint16_t z, rz;
-+ uint8_t buttons[4];
-+} __packed;
-+
-+struct ally_x_device {
-+ struct input_dev *input;
-+ struct hid_device *hdev;
-+ spinlock_t lock;
-+
-+ struct ff_report *ff_packet;
-+ struct work_struct output_worker;
-+ bool output_worker_initialized;
-+ /* Prevent multiple queued event due to the enforced delay in worker */
-+ bool update_qam_btn;
-+ /* Set if the QAM and AC buttons emit Xbox and Xbox+A */
-+ bool qam_btns_steam_mode;
-+ bool update_ff;
-+};
-+
-+struct ally_rgb_leds {
-+ struct hid_device *hdev;
-+ /* Need two dev here to enable the 3 step brightness */
-+ struct led_classdev led_bright_dev;
-+ struct led_classdev_mc led_rgb_dev;
-+ struct work_struct work;
-+ spinlock_t lock;
-+
-+ bool removed;
-+
-+ /* Update the main brightness 0-2 using a single raw write */
-+ bool update_bright;
-+ unsigned int brightness;
-+
-+ /* Update the RGB only to keep write efficient */
-+ bool update_rgb;
-+ uint8_t gamepad_red[4];
-+ uint8_t gamepad_green[4];
-+ uint8_t gamepad_blue[4];
-+
-+ /* Once the RGB is toggled this is set until next boot */
-+ bool rgb_software_mode;
-+};
-+
-+/* ROG Ally has many settings related to the gamepad, all using the same n-key endpoint */
-+struct ally_gamepad_cfg {
-+ struct hid_device *hdev;
-+ struct input_dev *input;
-+
-+ enum xpad_mode mode;
-+ /*
-+ * index: [joysticks/triggers][left(2 bytes), right(2 bytes)]
-+ * joysticks: 2 bytes: inner, outer
-+ * triggers: 2 bytes: lower, upper
-+ * min/max: 0-64
-+ */
-+ u8 deadzones[xpad_mode_mouse][2][4];
-+ /*
-+ * index: left, right
-+ * max: 64
-+ */
-+ u8 vibration_intensity[xpad_mode_mouse][2];
-+ /*
-+ * index: [joysticks][2 byte stepping per point]
-+ * - 4 points of 2 bytes each
-+ * - byte 0 of pair = stick move %
-+ * - byte 1 of pair = stick response %
-+ * - min/max: 1-63
-+ */
-+ bool supports_response_curves;
-+ u8 response_curve[xpad_mode_mouse][2][8];
-+ /*
-+ * left = byte 0, right = byte 1
-+ */
-+ bool supports_anti_deadzones;
-+ u8 anti_deadzones[xpad_mode_mouse][2];
-+ /*
-+ * index: [mode][phys pair][b1, b1 secondary, b2, b2 secondary, blocks of 11]
-+ */
-+ u8 key_mapping[xpad_mode_mouse][btn_pair_lt_rt][MAPPING_BLOCK_LEN];
-+ /*
-+ * index: [mode][button index]
-+ */
-+ u8 turbo_btns[xpad_mode_mouse][TURBO_BLOCK_LEN];
-+ /*
-+ * index: [joystick side][Y-stable, Y-min, Y-max, X-stable, X-min, X-max]
-+ */
-+ u32 js_calibrations[2][6];
-+ /*
-+ * index: [trigger side][stable, max]
-+ */
-+ u32 tr_calibrations[2][2];
-+};
-+
-+static struct ally_drvdata {
-+ struct hid_device *hdev;
-+ struct ally_x_device *ally_x;
-+ struct ally_gamepad_cfg *gamepad_cfg;
-+ struct ally_rgb_leds *led_rgb;
-+} drvdata;
-+
-+static int asus_dev_get_report(struct hid_device *hdev, u8 *out_buf, size_t out_buf_size)
-+{
-+ return hid_hw_raw_request(hdev, FEATURE_REPORT_ID, out_buf, out_buf_size,
-+ HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
-+}
-+
-+static int asus_dev_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size)
-+{
-+ unsigned char *dmabuf;
-+ int ret;
-+
-+ dmabuf = kmemdup(buf, buf_size, GFP_KERNEL);
-+ if (!dmabuf)
-+ return -ENOMEM;
-+
-+ ret = hid_hw_raw_request(hdev, buf[0], dmabuf, buf_size, HID_FEATURE_REPORT,
-+ HID_REQ_SET_REPORT);
-+ kfree(dmabuf);
-+
-+ return ret;
-+}
-+
-+/**************************************************************************************************/
-+/* ROG Ally gamepad i/o and force-feedback */
-+/**************************************************************************************************/
-+static int ally_x_raw_event(struct ally_x_device *ally_x, struct hid_report *report, u8 *data,
-+ int size)
-+{
-+ struct ally_x_input_report *in_report;
-+ unsigned long flags;
-+ u8 byte;
-+
-+ if (data[0] == 0x0B) {
-+ in_report = (struct ally_x_input_report *)&data[1];
-+
-+ input_report_abs(ally_x->input, ABS_X, in_report->x);
-+ input_report_abs(ally_x->input, ABS_Y, in_report->y);
-+ input_report_abs(ally_x->input, ABS_RX, in_report->rx);
-+ input_report_abs(ally_x->input, ABS_RY, in_report->ry);
-+ input_report_abs(ally_x->input, ABS_Z, in_report->z);
-+ input_report_abs(ally_x->input, ABS_RZ, in_report->rz);
-+
-+ byte = in_report->buttons[0];
-+ input_report_key(ally_x->input, BTN_A, byte & BIT(0));
-+ input_report_key(ally_x->input, BTN_B, byte & BIT(1));
-+ input_report_key(ally_x->input, BTN_X, byte & BIT(2));
-+ input_report_key(ally_x->input, BTN_Y, byte & BIT(3));
-+ input_report_key(ally_x->input, BTN_TL, byte & BIT(4));
-+ input_report_key(ally_x->input, BTN_TR, byte & BIT(5));
-+ input_report_key(ally_x->input, BTN_SELECT, byte & BIT(6));
-+ input_report_key(ally_x->input, BTN_START, byte & BIT(7));
-+
-+ byte = in_report->buttons[1];
-+ input_report_key(ally_x->input, BTN_THUMBL, byte & BIT(0));
-+ input_report_key(ally_x->input, BTN_THUMBR, byte & BIT(1));
-+ input_report_key(ally_x->input, BTN_MODE, byte & BIT(2));
-+
-+ byte = in_report->buttons[2];
-+ input_report_abs(ally_x->input, ABS_HAT0X, hat_values[byte][0]);
-+ input_report_abs(ally_x->input, ABS_HAT0Y, hat_values[byte][1]);
-+ }
-+ /*
-+ * The MCU used on Ally provides many devices: gamepad, keyboord, mouse, other.
-+ * The AC and QAM buttons route through another interface making it difficult to
-+ * use the events unless we grab those and use them here. Only works for Ally X.
-+ */
-+ else if (data[0] == 0x5A) {
-+ if (ally_x->qam_btns_steam_mode) {
-+ spin_lock_irqsave(&ally_x->lock, flags);
-+ if (data[1] == 0x38 && !ally_x->update_qam_btn) {
-+ ally_x->update_qam_btn = true;
-+ if (ally_x->output_worker_initialized)
-+ schedule_work(&ally_x->output_worker);
-+ }
-+ spin_unlock_irqrestore(&ally_x->lock, flags);
-+ /* Left/XBox button. Long press does ctrl+alt+del which we can't catch */
-+ input_report_key(ally_x->input, BTN_MODE, data[1] == 0xA6);
-+ } else {
-+ input_report_key(ally_x->input, KEY_F16, data[1] == 0xA6);
-+ input_report_key(ally_x->input, KEY_PROG1, data[1] == 0x38);
-+ }
-+ /* QAM long press */
-+ input_report_key(ally_x->input, KEY_F17, data[1] == 0xA7);
-+ /* QAM long press released */
-+ input_report_key(ally_x->input, KEY_F18, data[1] == 0xA8);
-+ }
-+
-+ input_sync(ally_x->input);
-+
-+ return 0;
-+}
-+
-+static struct input_dev *ally_x_alloc_input_dev(struct hid_device *hdev,
-+ const char *name_suffix)
-+{
-+ struct input_dev *input_dev;
-+
-+ input_dev = devm_input_allocate_device(&hdev->dev);
-+ if (!input_dev)
-+ return ERR_PTR(-ENOMEM);
-+
-+ input_dev->id.bustype = hdev->bus;
-+ input_dev->id.vendor = hdev->vendor;
-+ input_dev->id.product = hdev->product;
-+ input_dev->id.version = hdev->version;
-+ input_dev->uniq = hdev->uniq;
-+ input_dev->name = "ASUS ROG Ally X Gamepad";
-+
-+ input_set_drvdata(input_dev, hdev);
-+
-+ return input_dev;
-+}
-+
-+static int ally_x_play_effect(struct input_dev *idev, void *data, struct ff_effect *effect)
-+{
-+ struct ally_x_device *ally_x = drvdata.ally_x;
-+ unsigned long flags;
-+
-+ if (effect->type != FF_RUMBLE)
-+ return 0;
-+
-+ spin_lock_irqsave(&ally_x->lock, flags);
-+ ally_x->ff_packet->ff.magnitude_strong = effect->u.rumble.strong_magnitude / 512;
-+ ally_x->ff_packet->ff.magnitude_weak = effect->u.rumble.weak_magnitude / 512;
-+ ally_x->update_ff = true;
-+ spin_unlock_irqrestore(&ally_x->lock, flags);
-+
-+ if (ally_x->output_worker_initialized)
-+ schedule_work(&ally_x->output_worker);
-+
-+ return 0;
-+}
-+
-+static void ally_x_work(struct work_struct *work)
-+{
-+ struct ally_x_device *ally_x = container_of(work, struct ally_x_device, output_worker);
-+ struct ff_report *ff_report = NULL;
-+ bool update_qam = false;
-+ bool update_ff = false;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&ally_x->lock, flags);
-+ update_ff = ally_x->update_ff;
-+ if (ally_x->update_ff) {
-+ ff_report = kmemdup(ally_x->ff_packet, sizeof(*ally_x->ff_packet), GFP_KERNEL);
-+ ally_x->update_ff = false;
-+ }
-+ update_qam = ally_x->update_qam_btn;
-+ spin_unlock_irqrestore(&ally_x->lock, flags);
-+
-+ if (update_ff && ff_report) {
-+ ff_report->ff.magnitude_left = ff_report->ff.magnitude_strong;
-+ ff_report->ff.magnitude_right = ff_report->ff.magnitude_weak;
-+ asus_dev_set_report(ally_x->hdev, (u8 *)ff_report, sizeof(*ff_report));
-+ }
-+ kfree(ff_report);
-+
-+ if (update_qam) {
-+ /*
-+ * The sleeps here are required to allow steam to register the button combo.
-+ */
-+ usleep_range(1000, 2000);
-+ input_report_key(ally_x->input, BTN_MODE, 1);
-+ input_sync(ally_x->input);
-+
-+ msleep(80);
-+ input_report_key(ally_x->input, BTN_A, 1);
-+ input_sync(ally_x->input);
-+
-+ msleep(80);
-+ input_report_key(ally_x->input, BTN_A, 0);
-+ input_sync(ally_x->input);
-+
-+ msleep(80);
-+ input_report_key(ally_x->input, BTN_MODE, 0);
-+ input_sync(ally_x->input);
-+
-+ spin_lock_irqsave(&ally_x->lock, flags);
-+ ally_x->update_qam_btn = false;
-+ spin_unlock_irqrestore(&ally_x->lock, flags);
-+ }
-+}
-+
-+static struct input_dev *ally_x_setup_input(struct hid_device *hdev)
-+{
-+ int ret, abs_min = 0, js_abs_max = 65535, tr_abs_max = 1023;
-+ struct input_dev *input;
-+
-+ input = ally_x_alloc_input_dev(hdev, NULL);
-+ if (IS_ERR(input))
-+ return ERR_CAST(input);
-+
-+ input_set_abs_params(input, ABS_X, abs_min, js_abs_max, 0, 0);
-+ input_set_abs_params(input, ABS_Y, abs_min, js_abs_max, 0, 0);
-+ input_set_abs_params(input, ABS_RX, abs_min, js_abs_max, 0, 0);
-+ input_set_abs_params(input, ABS_RY, abs_min, js_abs_max, 0, 0);
-+ input_set_abs_params(input, ABS_Z, abs_min, tr_abs_max, 0, 0);
-+ input_set_abs_params(input, ABS_RZ, abs_min, tr_abs_max, 0, 0);
-+ input_set_abs_params(input, ABS_HAT0X, -1, 1, 0, 0);
-+ input_set_abs_params(input, ABS_HAT0Y, -1, 1, 0, 0);
-+ input_set_capability(input, EV_KEY, BTN_A);
-+ input_set_capability(input, EV_KEY, BTN_B);
-+ input_set_capability(input, EV_KEY, BTN_X);
-+ input_set_capability(input, EV_KEY, BTN_Y);
-+ input_set_capability(input, EV_KEY, BTN_TL);
-+ input_set_capability(input, EV_KEY, BTN_TR);
-+ input_set_capability(input, EV_KEY, BTN_SELECT);
-+ input_set_capability(input, EV_KEY, BTN_START);
-+ input_set_capability(input, EV_KEY, BTN_MODE);
-+ input_set_capability(input, EV_KEY, BTN_THUMBL);
-+ input_set_capability(input, EV_KEY, BTN_THUMBR);
-+
-+ input_set_capability(input, EV_KEY, KEY_PROG1);
-+ input_set_capability(input, EV_KEY, KEY_F16);
-+ input_set_capability(input, EV_KEY, KEY_F17);
-+ input_set_capability(input, EV_KEY, KEY_F18);
-+
-+ input_set_capability(input, EV_FF, FF_RUMBLE);
-+ input_ff_create_memless(input, NULL, ally_x_play_effect);
-+
-+ ret = input_register_device(input);
-+ if (ret)
-+ return ERR_PTR(ret);
-+
-+ return input;
-+}
-+
-+static ssize_t ally_x_qam_mode_show(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct ally_x_device *ally_x = drvdata.ally_x;
-+
-+ return sysfs_emit(buf, "%d\n", ally_x->qam_btns_steam_mode);
-+}
-+
-+static ssize_t ally_x_qam_mode_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct ally_x_device *ally_x = drvdata.ally_x;
-+ bool val;
-+ int ret;
-+
-+ ret = kstrtobool(buf, &val);
-+ if (ret < 0)
-+ return ret;
-+
-+ ally_x->qam_btns_steam_mode = val;
-+
-+ return count;
-+}
-+ALLY_DEVICE_ATTR_RW(ally_x_qam_mode, qam_mode);
-+
-+static struct ally_x_device *ally_x_create(struct hid_device *hdev)
-+{
-+ uint8_t max_output_report_size;
-+ struct ally_x_device *ally_x;
-+ struct ff_report *report;
-+ int ret;
-+
-+ ally_x = devm_kzalloc(&hdev->dev, sizeof(*ally_x), GFP_KERNEL);
-+ if (!ally_x)
-+ return ERR_PTR(-ENOMEM);
-+
-+ ally_x->hdev = hdev;
-+ INIT_WORK(&ally_x->output_worker, ally_x_work);
-+ spin_lock_init(&ally_x->lock);
-+ ally_x->output_worker_initialized = true;
-+ ally_x->qam_btns_steam_mode =
-+ true; /* Always default to steam mode, it can be changed by userspace attr */
-+
-+ max_output_report_size = sizeof(struct ally_x_input_report);
-+ report = devm_kzalloc(&hdev->dev, sizeof(*report), GFP_KERNEL);
-+ if (!report) {
-+ ret = -ENOMEM;
-+ goto free_ally_x;
-+ }
-+
-+ /* None of these bytes will change for the FF command for now */
-+ report->report_id = 0x0D;
-+ report->ff.enable = 0x0F; /* Enable all by default */
-+ report->ff.pulse_sustain_10ms = 0xFF; /* Duration */
-+ report->ff.pulse_release_10ms = 0x00; /* Start Delay */
-+ report->ff.loop_count = 0xEB; /* Loop Count */
-+ ally_x->ff_packet = report;
-+
-+ ally_x->input = ally_x_setup_input(hdev);
-+ if (IS_ERR(ally_x->input)) {
-+ ret = PTR_ERR(ally_x->input);
-+ goto free_ff_packet;
-+ }
-+
-+ if (sysfs_create_file(&hdev->dev.kobj, &dev_attr_ally_x_qam_mode.attr)) {
-+ ret = -ENODEV;
-+ goto unregister_input;
-+ }
-+
-+ ally_x->update_ff = true;
-+ if (ally_x->output_worker_initialized)
-+ schedule_work(&ally_x->output_worker);
-+
-+ hid_info(hdev, "Registered Ally X controller using %s\n",
-+ dev_name(&ally_x->input->dev));
-+ return ally_x;
-+
-+unregister_input:
-+ input_unregister_device(ally_x->input);
-+free_ff_packet:
-+ kfree(ally_x->ff_packet);
-+free_ally_x:
-+ kfree(ally_x);
-+ return ERR_PTR(ret);
-+}
-+
-+static void ally_x_remove(struct hid_device *hdev)
-+{
-+ struct ally_x_device *ally_x = drvdata.ally_x;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&ally_x->lock, flags);
-+ ally_x->output_worker_initialized = false;
-+ spin_unlock_irqrestore(&ally_x->lock, flags);
-+ cancel_work_sync(&ally_x->output_worker);
-+ sysfs_remove_file(&hdev->dev.kobj, &dev_attr_ally_x_qam_mode.attr);
-+}
-+
-+/**************************************************************************************************/
-+/* ROG Ally configuration */
-+/**************************************************************************************************/
-+static int __gamepad_write_all_to_mcu(struct hid_device *hdev,
-+ struct ally_gamepad_cfg *ally_cfg);
-+
-+static int process_key_code(const struct KeyCode *codes, int code_count, const char *buf_copy,
-+ u8 *out, int out_idx)
-+{
-+ for (int i = 0; i < code_count; i++) {
-+ if (strcmp(buf_copy, codes[i].label) == 0) {
-+ out[out_idx] = codes[i].code;
-+ return 0; // Found
-+ }
-+ }
-+ return -EINVAL; // Not found
-+}
-+
-+static int __string_to_key_code(const char *buf, u8 *out, int out_len)
-+{
-+ char buf_copy[32];
-+ u8 *save_buf;
-+
-+ if (out_len != BTN_CODE_LEN)
-+ return -EINVAL;
-+
-+ save_buf = kzalloc(out_len, GFP_KERNEL);
-+ if (!save_buf)
-+ return -ENOMEM;
-+ memcpy(save_buf, out, out_len);
-+ memset(out, 0, out_len); /* always clear before adjusting */
-+
-+ strscpy(buf_copy, buf);
-+ buf_copy[strcspn(buf_copy, "\n")] = 0;
-+
-+ /* Gamepad group */
-+ out[0] = 0x01;
-+ if (process_key_code(gamepad_codes, ARRAY_SIZE(gamepad_codes), buf_copy, out, 1) == 0)
-+ goto success;
-+
-+ /* Keyboard group */
-+ out[0] = 0x02;
-+ if (process_key_code(keyboard_codes, ARRAY_SIZE(keyboard_codes), buf_copy, out, 2) == 0)
-+ goto success;
-+
-+ /* Mouse group */
-+ out[0] = 0x03;
-+ if (process_key_code(mouse_codes, ARRAY_SIZE(mouse_codes), buf_copy, out, 4) == 0)
-+ goto success;
-+
-+ /* Media group */
-+ out[0] = 0x05;
-+ if (process_key_code(media_codes, ARRAY_SIZE(media_codes), buf_copy, out, 3) == 0)
-+ goto success;
-+
-+ /* Restore bytes if invalid input */
-+ memcpy(out, save_buf, out_len);
-+ kfree(save_buf);
-+ return -EINVAL;
-+
-+success:
-+ kfree(save_buf);
-+ return 0;
-+}
-+
-+static const char *key_code_to_string(const struct KeyCode *codes, int code_count, u8 code)
-+{
-+ for (int i = 0; i < code_count; i++) {
-+ if (codes[i].code == code)
-+ return codes[i].label;
-+ }
-+ return "";
-+}
-+
-+static u8 *__get_btn_block(struct ally_gamepad_cfg *ally_cfg, enum btn_pair pair,
-+ enum btn_pair_side side, bool secondary)
-+{
-+ int offs;
-+
-+ offs = side ? MAPPING_BLOCK_LEN / 2 : 0;
-+ offs = secondary ? offs + BTN_CODE_LEN : offs;
-+ return ally_cfg->key_mapping[ally_cfg->mode - 1][pair - 1] + offs;
-+}
-+
-+static const char *__btn_map_to_string(struct ally_gamepad_cfg *ally_cfg, enum btn_pair pair,
-+ enum btn_pair_side side, bool secondary)
-+{
-+ u8 *out_arg = __get_btn_block(ally_cfg, pair, side, secondary);
-+
-+ switch (out_arg[0]) {
-+ case 0x01: // Gamepad buttons
-+ return key_code_to_string(gamepad_codes, ARRAY_SIZE(gamepad_codes), out_arg[1]);
-+ case 0x02: // Keyboard keys
-+ return key_code_to_string(keyboard_codes, ARRAY_SIZE(keyboard_codes),
-+ out_arg[2]);
-+ case 0x03: // Mouse buttons
-+ return key_code_to_string(mouse_codes, ARRAY_SIZE(mouse_codes), out_arg[4]);
-+ case 0x05: // Media controls
-+ return key_code_to_string(media_codes, ARRAY_SIZE(media_codes), out_arg[3]);
-+ default:
-+ return "";
-+ }
-+}
-+
-+/* ASUS ROG Ally device specific attributes */
-+
-+/* This should be called before any attempts to set device functions */
-+static int __gamepad_check_ready(struct hid_device *hdev)
-+{
-+ int ret, count;
-+ u8 *hidbuf;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ ret = 0;
-+ for (count = 0; count < READY_MAX_TRIES; count++) {
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_check_ready;
-+ hidbuf[3] = 01;
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ hid_dbg(hdev, "ROG Ally check failed set report: %d\n", ret);
-+
-+ hidbuf[0] = hidbuf[1] = hidbuf[2] = hidbuf[3] = 0;
-+ ret = asus_dev_get_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ hid_dbg(hdev, "ROG Ally check failed get report: %d\n", ret);
-+
-+ ret = hidbuf[2] == xpad_cmd_check_ready;
-+ if (ret)
-+ break;
-+ usleep_range(
-+ 1000,
-+ 2000); /* don't spam the entire loop in less than USB response time */
-+ }
-+
-+ if (count == READY_MAX_TRIES)
-+ hid_warn(hdev, "ROG Ally never responded with a ready\n");
-+
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+/* BUTTON REMAPPING *******************************************************************************/
-+static void __btn_pair_to_pkt(struct ally_gamepad_cfg *ally_cfg, enum btn_pair pair, u8 *out,
-+ int out_len)
-+{
-+ out[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ out[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ out[2] = xpad_cmd_set_mapping;
-+ out[3] = pair;
-+ out[4] = xpad_cmd_len_mapping;
-+ memcpy(&out[5], &ally_cfg->key_mapping[ally_cfg->mode - 1][pair - 1],
-+ MAPPING_BLOCK_LEN);
-+}
-+
-+/* Store the button setting in driver data. Does not apply to device until __gamepad_set_mapping */
-+static int __gamepad_mapping_store(struct ally_gamepad_cfg *ally_cfg, const char *buf,
-+ enum btn_pair pair, int side, bool secondary)
-+{
-+ u8 *out_arg;
-+
-+ out_arg = __get_btn_block(ally_cfg, pair, side, secondary);
-+
-+ return __string_to_key_code(buf, out_arg, BTN_CODE_LEN);
-+}
-+
-+/* Apply the mapping pair to the device */
-+static int __gamepad_set_mapping(struct hid_device *hdev, struct ally_gamepad_cfg *ally_cfg,
-+ enum btn_pair pair)
-+{
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ __btn_pair_to_pkt(ally_cfg, pair, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+
-+ kfree(hidbuf);
-+
-+ return ret;
-+}
-+
-+static ssize_t btn_mapping_apply_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ struct hid_device *hdev = to_hid_device(dev);
-+ int ret;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ ret = __gamepad_write_all_to_mcu(hdev, ally_cfg);
-+ if (ret < 0)
-+ return ret;
-+
-+ return count;
-+}
-+ALLY_DEVICE_ATTR_WO(btn_mapping_apply, apply_all);
-+
-+/* BUTTON TURBO ***********************************************************************************/
-+static int __btn_turbo_index(enum btn_pair pair, int side)
-+{
-+ return (pair - 1) * (2 * TURBO_BLOCK_STEP) + (side * TURBO_BLOCK_STEP);
-+};
-+
-+static int __gamepad_turbo_show(struct device *dev, enum btn_pair pair, int side)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ return ally_cfg->turbo_btns[ally_cfg->mode - 1][__btn_turbo_index(pair, side)];
-+};
-+
-+static int __gamepad_turbo_store(struct device *dev, const char *buf, enum btn_pair pair,
-+ int side)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ int ret, val;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ ret = kstrtoint(buf, 0, &val);
-+ if (ret)
-+ return ret;
-+ if (val < 0 || val > 16)
-+ return -EINVAL;
-+
-+ ally_cfg->turbo_btns[ally_cfg->mode - 1][__btn_turbo_index(pair, side)] = val;
-+
-+ return 0;
-+};
-+
-+/* button map attributes, regular and macro*/
-+ALLY_BTN_MAPPING(m2, btn_pair_m1_m2, btn_pair_side_left);
-+ALLY_BTN_MAPPING(m1, btn_pair_m1_m2, btn_pair_side_right);
-+ALLY_BTN_MAPPING(a, btn_pair_a_b, btn_pair_side_left);
-+ALLY_BTN_MAPPING(b, btn_pair_a_b, btn_pair_side_right);
-+ALLY_BTN_MAPPING(x, btn_pair_x_y, btn_pair_side_left);
-+ALLY_BTN_MAPPING(y, btn_pair_x_y, btn_pair_side_right);
-+ALLY_BTN_MAPPING(lb, btn_pair_lb_rb, btn_pair_side_left);
-+ALLY_BTN_MAPPING(rb, btn_pair_lb_rb, btn_pair_side_right);
-+ALLY_BTN_MAPPING(ls, btn_pair_ls_rs, btn_pair_side_left);
-+ALLY_BTN_MAPPING(rs, btn_pair_ls_rs, btn_pair_side_right);
-+ALLY_BTN_MAPPING(lt, btn_pair_lt_rt, btn_pair_side_left);
-+ALLY_BTN_MAPPING(rt, btn_pair_lt_rt, btn_pair_side_right);
-+ALLY_BTN_MAPPING(dpad_u, btn_pair_dpad_u_d, btn_pair_side_left);
-+ALLY_BTN_MAPPING(dpad_d, btn_pair_dpad_u_d, btn_pair_side_right);
-+ALLY_BTN_MAPPING(dpad_l, btn_pair_dpad_l_r, btn_pair_side_left);
-+ALLY_BTN_MAPPING(dpad_r, btn_pair_dpad_l_r, btn_pair_side_right);
-+ALLY_BTN_MAPPING(view, btn_pair_view_menu, btn_pair_side_left);
-+ALLY_BTN_MAPPING(menu, btn_pair_view_menu, btn_pair_side_right);
-+
-+static void __gamepad_mapping_xpad_default(struct ally_gamepad_cfg *ally_cfg)
-+{
-+ memcpy(&ally_cfg->key_mapping[0][0], &XPAD_DEF1, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][1], &XPAD_DEF2, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][2], &XPAD_DEF3, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][3], &XPAD_DEF4, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][4], &XPAD_DEF5, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][5], &XPAD_DEF6, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][6], &XPAD_DEF7, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][7], &XPAD_DEF8, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[0][8], &XPAD_DEF9, MAPPING_BLOCK_LEN);
-+}
-+
-+static void __gamepad_mapping_wasd_default(struct ally_gamepad_cfg *ally_cfg)
-+{
-+ memcpy(&ally_cfg->key_mapping[1][0], &WASD_DEF1, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][1], &WASD_DEF2, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][2], &WASD_DEF3, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][3], &WASD_DEF4, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][4], &WASD_DEF5, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][5], &WASD_DEF6, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][6], &WASD_DEF7, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][7], &WASD_DEF8, MAPPING_BLOCK_LEN);
-+ memcpy(&ally_cfg->key_mapping[1][8], &WASD_DEF9, MAPPING_BLOCK_LEN);
-+}
-+
-+static ssize_t btn_mapping_reset_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ switch (ally_cfg->mode) {
-+ case xpad_mode_game:
-+ __gamepad_mapping_xpad_default(ally_cfg);
-+ break;
-+ case xpad_mode_wasd:
-+ __gamepad_mapping_wasd_default(ally_cfg);
-+ break;
-+ default:
-+ __gamepad_mapping_xpad_default(ally_cfg);
-+ break;
-+ }
-+
-+ return count;
-+}
-+
-+ALLY_DEVICE_ATTR_WO(btn_mapping_reset, reset_btn_mapping);
-+
-+/* GAMEPAD MODE ***********************************************************************************/
-+static ssize_t __gamepad_set_mode(struct hid_device *hdev, struct ally_gamepad_cfg *ally_cfg,
-+ int val)
-+{
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_mode;
-+ hidbuf[3] = xpad_cmd_len_mode;
-+ hidbuf[4] = val;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+ ret = __gamepad_write_all_to_mcu(hdev, ally_cfg);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+report_fail:
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static ssize_t gamepad_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ return sysfs_emit(buf, "%d\n", ally_cfg->mode);
-+}
-+
-+static ssize_t gamepad_mode_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct hid_device *hdev = to_hid_device(dev);
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ int ret, val;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ ret = kstrtoint(buf, 0, &val);
-+ if (ret)
-+ return ret;
-+
-+ if (val < xpad_mode_game || val > xpad_mode_mouse)
-+ return -EINVAL;
-+
-+ ally_cfg->mode = val;
-+
-+ ret = __gamepad_set_mode(hdev, ally_cfg, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ return count;
-+}
-+
-+DEVICE_ATTR_RW(gamepad_mode);
-+
-+/* VIBRATION INTENSITY ****************************************************************************/
-+static ssize_t gamepad_vibration_intensity_index_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ return sysfs_emit(buf, "left right\n");
-+}
-+
-+ALLY_DEVICE_ATTR_RO(gamepad_vibration_intensity_index, vibration_intensity_index);
-+
-+static ssize_t __gamepad_write_vibe_intensity_to_mcu(struct hid_device *hdev,
-+ struct ally_gamepad_cfg *ally_cfg)
-+{
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_vibe_intensity;
-+ hidbuf[3] = xpad_cmd_len_vibe_intensity;
-+ hidbuf[4] = ally_cfg->vibration_intensity[ally_cfg->mode - 1][btn_pair_side_left];
-+ hidbuf[5] = ally_cfg->vibration_intensity[ally_cfg->mode - 1][btn_pair_side_right];
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+report_fail:
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static ssize_t gamepad_vibration_intensity_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ return sysfs_emit(
-+ buf, "%d %d\n",
-+ ally_cfg->vibration_intensity[ally_cfg->mode - 1][btn_pair_side_left],
-+ ally_cfg->vibration_intensity[ally_cfg->mode - 1][btn_pair_side_right]);
-+}
-+
-+static ssize_t gamepad_vibration_intensity_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf,
-+ size_t count)
-+{
-+ struct hid_device *hdev = to_hid_device(dev);
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ u32 left, right;
-+ int ret;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ if (sscanf(buf, "%d %d", &left, &right) != 2)
-+ return -EINVAL;
-+
-+ if (left > 64 || right > 64)
-+ return -EINVAL;
-+
-+ ally_cfg->vibration_intensity[ally_cfg->mode - 1][btn_pair_side_left] = left;
-+ ally_cfg->vibration_intensity[ally_cfg->mode - 1][btn_pair_side_right] = right;
-+
-+ ret = __gamepad_write_vibe_intensity_to_mcu(hdev, ally_cfg);
-+ if (ret < 0)
-+ return ret;
-+
-+ return count;
-+}
-+
-+ALLY_DEVICE_ATTR_RW(gamepad_vibration_intensity, vibration_intensity);
-+
-+/* ROOT LEVEL ATTRS *******************************************************************************/
-+static struct attribute *gamepad_device_attrs[] = {
-+ &dev_attr_gamepad_mode.attr,
-+ &dev_attr_btn_mapping_reset.attr,
-+ &dev_attr_btn_mapping_apply.attr,
-+ &dev_attr_gamepad_vibration_intensity.attr,
-+ &dev_attr_gamepad_vibration_intensity_index.attr,
-+ NULL
-+};
-+
-+static const struct attribute_group ally_controller_attr_group = {
-+ .attrs = gamepad_device_attrs,
-+};
-+
-+/* ANALOGUE DEADZONES *****************************************************************************/
-+static ssize_t __gamepad_set_deadzones(struct hid_device *hdev,
-+ struct ally_gamepad_cfg *ally_cfg)
-+{
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_js_dz;
-+ hidbuf[3] = xpad_cmd_len_deadzone;
-+ hidbuf[4] = ally_cfg->deadzones[ally_cfg->mode - 1][0][0];
-+ hidbuf[5] = ally_cfg->deadzones[ally_cfg->mode - 1][0][1];
-+ hidbuf[6] = ally_cfg->deadzones[ally_cfg->mode - 1][0][2];
-+ hidbuf[7] = ally_cfg->deadzones[ally_cfg->mode - 1][0][3];
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto end;
-+
-+ hidbuf[2] = xpad_cmd_set_tr_dz;
-+ hidbuf[4] = ally_cfg->deadzones[ally_cfg->mode - 1][1][0];
-+ hidbuf[5] = ally_cfg->deadzones[ally_cfg->mode - 1][1][1];
-+ hidbuf[6] = ally_cfg->deadzones[ally_cfg->mode - 1][1][2];
-+ hidbuf[7] = ally_cfg->deadzones[ally_cfg->mode - 1][1][3];
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto end;
-+
-+end:
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static ssize_t __gamepad_store_deadzones(struct ally_gamepad_cfg *ally_cfg, enum xpad_axis axis,
-+ const char *buf)
-+{
-+ int cmd, side, is_tr;
-+ u32 inner, outer;
-+
-+ if (sscanf(buf, "%d %d", &inner, &outer) != 2)
-+ return -EINVAL;
-+
-+ if (inner > 64 || outer > 64 || inner > outer)
-+ return -EINVAL;
-+
-+ is_tr = axis > xpad_axis_xy_right;
-+ side = axis == xpad_axis_xy_right || axis == xpad_axis_z_right ? 2 : 0;
-+ cmd = is_tr ? xpad_cmd_set_js_dz : xpad_cmd_set_tr_dz;
-+
-+ ally_cfg->deadzones[ally_cfg->mode - 1][is_tr][side] = inner;
-+ ally_cfg->deadzones[ally_cfg->mode - 1][is_tr][side + 1] = outer;
-+
-+ return 0;
-+}
-+
-+static ssize_t axis_xyz_deadzone_index_show(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ return sysfs_emit(buf, "inner outer\n");
-+}
-+
-+ALLY_DEVICE_ATTR_RO(axis_xyz_deadzone_index, deadzone_index);
-+
-+ALLY_AXIS_DEADZONE(xpad_axis_xy_left, deadzone);
-+ALLY_AXIS_DEADZONE(xpad_axis_xy_right, deadzone);
-+ALLY_AXIS_DEADZONE(xpad_axis_z_left, deadzone);
-+ALLY_AXIS_DEADZONE(xpad_axis_z_right, deadzone);
-+
-+/* ANTI-DEADZONES *********************************************************************************/
-+static ssize_t __gamepad_write_js_ADZ_to_mcu(struct hid_device *hdev,
-+ struct ally_gamepad_cfg *ally_cfg)
-+{
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_adz;
-+ hidbuf[3] = xpad_cmd_len_adz;
-+ hidbuf[4] = ally_cfg->anti_deadzones[ally_cfg->mode - 1][btn_pair_side_left];
-+ hidbuf[5] = ally_cfg->anti_deadzones[ally_cfg->mode - 1][btn_pair_side_right];
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+report_fail:
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static ssize_t __gamepad_js_ADZ_store(struct device *dev, const char *buf,
-+ enum btn_pair_side side)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ int ret, val;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ ret = kstrtoint(buf, 0, &val);
-+ if (ret)
-+ return ret;
-+
-+ if (val < 0 || val > 32)
-+ return -EINVAL;
-+
-+ ally_cfg->anti_deadzones[ally_cfg->mode - 1][side] = val;
-+
-+ return ret;
-+}
-+
-+static ssize_t xpad_axis_xy_left_ADZ_show(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ return sysfs_emit(buf, "%d\n",
-+ ally_cfg->anti_deadzones[ally_cfg->mode - 1][btn_pair_side_left]);
-+}
-+
-+static ssize_t xpad_axis_xy_left_ADZ_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int ret = __gamepad_js_ADZ_store(dev, buf, btn_pair_side_left);
-+
-+ if (ret)
-+ return ret;
-+
-+ return count;
-+}
-+
-+ALLY_DEVICE_ATTR_RW(xpad_axis_xy_left_ADZ, anti_deadzone);
-+
-+static ssize_t xpad_axis_xy_right_ADZ_show(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ return sysfs_emit(buf, "%d\n",
-+ ally_cfg->anti_deadzones[ally_cfg->mode - 1][btn_pair_side_right]);
-+}
-+
-+static ssize_t xpad_axis_xy_right_ADZ_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int ret = __gamepad_js_ADZ_store(dev, buf, btn_pair_side_right);
-+
-+ if (ret)
-+ return ret;
-+
-+ return count;
-+}
-+
-+ALLY_DEVICE_ATTR_RW(xpad_axis_xy_right_ADZ, anti_deadzone);
-+
-+/* JS RESPONSE CURVES *****************************************************************************/
-+static ssize_t rc_point_index_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ return sysfs_emit(buf, "move response\n");
-+}
-+
-+ALLY_DEVICE_ATTR_RO(rc_point_index, rc_point_index);
-+
-+static ssize_t __gamepad_write_response_curves_to_mcu(struct hid_device *hdev,
-+ struct ally_gamepad_cfg *ally_cfg)
-+{
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_response_curve;
-+ hidbuf[3] = xpad_cmd_len_response_curve;
-+ hidbuf[4] = 0x01;
-+ memcpy(&hidbuf[5], &ally_cfg->response_curve[ally_cfg->mode - 1][btn_pair_side_left],
-+ 8);
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+ hidbuf[4] = 0x02;
-+ memcpy(&hidbuf[5], &ally_cfg->response_curve[ally_cfg->mode - 1][btn_pair_side_right],
-+ 8);
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+report_fail:
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static ssize_t __gamepad_store_response_curve(struct device *dev, const char *buf,
-+ enum btn_pair_side side, int point)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ u32 move, response;
-+ int idx;
-+
-+ idx = (point - 1) * 2;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ if (sscanf(buf, "%d %d", &move, &response) != 2)
-+ return -EINVAL;
-+
-+ if (move > 64 || response > 64)
-+ return -EINVAL;
-+
-+ ally_cfg->response_curve[ally_cfg->mode - 1][side][idx] = move;
-+ ally_cfg->response_curve[ally_cfg->mode - 1][side][idx + 1] = response;
-+
-+ return 0;
-+}
-+
-+ALLY_JS_RC_POINT(left, 1, rc_point_);
-+ALLY_JS_RC_POINT(left, 2, rc_point_);
-+ALLY_JS_RC_POINT(left, 3, rc_point_);
-+ALLY_JS_RC_POINT(left, 4, rc_point_);
-+
-+ALLY_JS_RC_POINT(right, 1, rc_point_);
-+ALLY_JS_RC_POINT(right, 2, rc_point_);
-+ALLY_JS_RC_POINT(right, 3, rc_point_);
-+ALLY_JS_RC_POINT(right, 4, rc_point_);
-+
-+/* CALIBRATIONS ***********************************************************************************/
-+static int __gamepad_get_calibration(struct hid_device *hdev)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ u8 *hidbuf;
-+ int ret, i;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < 2; i++) {
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = 0xD0;
-+ hidbuf[2] = 0x03;
-+ hidbuf[3] = i + 1; // 0x01 JS, 0x02 TR
-+ hidbuf[4] = 0x20;
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0) {
-+ hid_warn(hdev, "ROG Ally check failed set report: %d\n", ret);
-+ goto cleanup;
-+ }
-+
-+ memset(hidbuf, 0, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ ret = asus_dev_get_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0 || hidbuf[5] != 1) {
-+ hid_warn(hdev, "ROG Ally check failed get report: %d\n", ret);
-+ goto cleanup;
-+ }
-+
-+ if (i == 0) {
-+ /* Joystick calibration */
-+ /* [left][index] is Y: stable, min, max. X: stable, min, max */
-+ ally_cfg->js_calibrations[0][3] = (hidbuf[6] << 8) | hidbuf[7];
-+ ally_cfg->js_calibrations[0][4] = (hidbuf[8] << 8) | hidbuf[9];
-+ ally_cfg->js_calibrations[0][5] = (hidbuf[10] << 8) | hidbuf[11];
-+ ally_cfg->js_calibrations[0][0] = (hidbuf[12] << 8) | hidbuf[13];
-+ ally_cfg->js_calibrations[0][1] = (hidbuf[14] << 8) | hidbuf[15];
-+ ally_cfg->js_calibrations[0][2] = (hidbuf[16] << 8) | hidbuf[17];
-+ /* [right][index] is Y: stable, min, max. X: stable, min, max */
-+ ally_cfg->js_calibrations[1][0] = (hidbuf[24] << 8) | hidbuf[25];
-+ ally_cfg->js_calibrations[1][1] = (hidbuf[26] << 8) | hidbuf[27];
-+ ally_cfg->js_calibrations[1][2] = (hidbuf[28] << 8) | hidbuf[29];
-+ ally_cfg->js_calibrations[1][3] = (hidbuf[18] << 8) | hidbuf[19];
-+ ally_cfg->js_calibrations[1][4] = (hidbuf[20] << 8) | hidbuf[21];
-+ ally_cfg->js_calibrations[1][5] = (hidbuf[22] << 8) | hidbuf[23];
-+ } else {
-+ /* Trigger calibration */
-+ /* [left/right][stable/max] */
-+ ally_cfg->tr_calibrations[0][0] = (hidbuf[6] << 8) | hidbuf[7];
-+ ally_cfg->tr_calibrations[0][1] = (hidbuf[8] << 8) | hidbuf[9];
-+ ally_cfg->tr_calibrations[1][0] = (hidbuf[10] << 8) | hidbuf[11];
-+ ally_cfg->tr_calibrations[1][1] = (hidbuf[12] << 8) | hidbuf[13];
-+ }
-+ }
-+
-+cleanup:
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static ssize_t __gamepad_write_cal_to_mcu(struct device *dev, enum xpad_axis axis)
-+{
-+ struct hid_device *hdev = to_hid_device(dev);
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ u8 *c, side, pkt_len, data_len;
-+ int ret, cal, checksum = 0;
-+ u8 *hidbuf;
-+ int *head;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ side = axis == xpad_axis_xy_right || axis == xpad_axis_z_right ? 1 : 0;
-+ pkt_len = axis > xpad_axis_xy_right ? 0x06 : 0x0E;
-+ data_len = axis > xpad_axis_xy_right ? 2 : 6;
-+ head = axis > xpad_axis_xy_right ? ally_cfg->tr_calibrations[side] :
-+ ally_cfg->js_calibrations[side];
-+
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_calibration;
-+ hidbuf[3] = pkt_len;
-+ hidbuf[4] = 0x01; /* second command (write calibration) */
-+ hidbuf[5] = axis;
-+ c = &hidbuf[6]; /* pointer to data start */
-+
-+ for (size_t i = 0; i < data_len; i++) {
-+ cal = head[i];
-+ *c = (u8)((cal & 0xff00) >> 8);
-+ checksum += *c;
-+ c += 1;
-+ *c = (u8)(cal & 0xff);
-+ checksum += *c;
-+ c += 1;
-+ }
-+
-+ hidbuf[6 + data_len * 2] = checksum;
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+ memset(hidbuf, 0, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_calibration;
-+ hidbuf[3] = xpad_cmd_len_calibration3;
-+ hidbuf[4] = 0x03; /* second command (apply the calibration that was written) */
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ goto report_fail;
-+
-+report_fail:
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static ssize_t __gamepad_cal_store(struct device *dev, const char *buf, enum xpad_axis axis)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ u32 x_stable, x_min, x_max, y_stable, y_min, y_max, side;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ if (axis == xpad_axis_xy_left || axis == xpad_axis_xy_right) {
-+ if (sscanf(buf, "%d %d %d %d %d %d", &x_stable, &x_min, &x_max, &y_stable,
-+ &y_min, &y_max) != 6)
-+ return -EINVAL;
-+
-+ side = axis == xpad_axis_xy_right || axis == xpad_axis_z_right ? 1 : 0;
-+ /* stored in reverse order for easy copy to packet */
-+ ally_cfg->js_calibrations[side][0] = y_stable;
-+ ally_cfg->js_calibrations[side][1] = y_min;
-+ ally_cfg->js_calibrations[side][2] = y_max;
-+ ally_cfg->js_calibrations[side][3] = x_stable;
-+ ally_cfg->js_calibrations[side][4] = x_min;
-+ ally_cfg->js_calibrations[side][5] = x_max;
-+
-+ return __gamepad_write_cal_to_mcu(dev, axis);
-+ }
-+ if (sscanf(buf, "%d %d", &x_stable, &x_max) != 2)
-+ return -EINVAL;
-+
-+ side = axis == xpad_axis_xy_right || axis == xpad_axis_z_right ? 1 : 0;
-+ /* stored in reverse order for easy copy to packet */
-+ ally_cfg->tr_calibrations[side][0] = x_stable;
-+ ally_cfg->tr_calibrations[side][1] = x_max;
-+
-+ return __gamepad_write_cal_to_mcu(dev, axis);
-+}
-+
-+static ssize_t __gamepad_cal_show(struct device *dev, char *buf, enum xpad_axis axis)
-+{
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
-+ int side = (axis == xpad_axis_xy_right || axis == xpad_axis_z_right) ? 1 : 0;
-+
-+ if (!drvdata.gamepad_cfg)
-+ return -ENODEV;
-+
-+ if (axis == xpad_axis_xy_left || axis == xpad_axis_xy_right) {
-+ return sysfs_emit(
-+ buf, "%d %d %d %d %d %d\n", ally_cfg->js_calibrations[side][3],
-+ ally_cfg->js_calibrations[side][4], ally_cfg->js_calibrations[side][5],
-+ ally_cfg->js_calibrations[side][0], ally_cfg->js_calibrations[side][1],
-+ ally_cfg->js_calibrations[side][2]);
-+ }
-+
-+ return sysfs_emit(buf, "%d %d\n", ally_cfg->tr_calibrations[side][0],
-+ ally_cfg->tr_calibrations[side][1]);
-+}
-+
-+ALLY_CAL_ATTR(xpad_axis_xy_left_cal, xpad_axis_xy_left, calibration);
-+ALLY_CAL_ATTR(xpad_axis_xy_right_cal, xpad_axis_xy_right, calibration);
-+ALLY_CAL_ATTR(xpad_axis_z_left_cal, xpad_axis_z_left, calibration);
-+ALLY_CAL_ATTR(xpad_axis_z_right_cal, xpad_axis_z_right, calibration);
-+
-+static ssize_t xpad_axis_xy_cal_index_show(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ return sysfs_emit(buf, "x_stable x_min x_max y_stable y_min y_max\n");
-+}
-+
-+ALLY_DEVICE_ATTR_RO(xpad_axis_xy_cal_index, calibration_index);
-+
-+static ssize_t xpad_axis_z_cal_index_show(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ return sysfs_emit(buf, "z_stable z_max\n");
-+}
-+
-+ALLY_DEVICE_ATTR_RO(xpad_axis_z_cal_index, calibration_index);
-+
-+static ssize_t __gamepad_cal_reset(struct device *dev, const char *buf, enum xpad_axis axis)
-+{
-+ struct hid_device *hdev = to_hid_device(dev);
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+
-+ /* Write the reset value, then apply it */
-+ for (u8 cmd = 0x02; cmd <= 0x03; cmd++) {
-+ memset(hidbuf, 0, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_calibration;
-+ hidbuf[3] = (cmd == 0x02) ? xpad_cmd_len_calibration2 :
-+ xpad_cmd_len_calibration3;
-+ hidbuf[4] = cmd;
-+ hidbuf[5] = axis;
-+
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+ if (ret < 0)
-+ break;
-+ }
-+
-+ __gamepad_get_calibration(hdev);
-+
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+ALLY_CAL_RESET_ATTR(xpad_axis_xy_left_cal_reset, xpad_axis_xy_left, calibration_reset);
-+ALLY_CAL_RESET_ATTR(xpad_axis_xy_right_cal_reset, xpad_axis_xy_right, calibration_reset);
-+ALLY_CAL_RESET_ATTR(xpad_axis_z_left_cal_reset, xpad_axis_z_left, calibration_reset);
-+ALLY_CAL_RESET_ATTR(xpad_axis_z_right_cal_reset, xpad_axis_z_right, calibration_reset);
-+
-+static struct attribute *gamepad_axis_xy_left_attrs[] = {
-+ &dev_attr_xpad_axis_xy_left_deadzone.attr,
-+ &dev_attr_axis_xyz_deadzone_index.attr,
-+ &dev_attr_xpad_axis_xy_left_ADZ.attr,
-+ &dev_attr_xpad_axis_xy_left_cal_reset.attr,
-+ &dev_attr_xpad_axis_xy_left_cal.attr,
-+ &dev_attr_xpad_axis_xy_cal_index.attr,
-+ &dev_attr_rc_point_left_1.attr,
-+ &dev_attr_rc_point_left_2.attr,
-+ &dev_attr_rc_point_left_3.attr,
-+ &dev_attr_rc_point_left_4.attr,
-+ &dev_attr_rc_point_index.attr,
-+ NULL
-+};
-+static const struct attribute_group ally_controller_axis_xy_left_attr_group = {
-+ .name = "axis_xy_left",
-+ .attrs = gamepad_axis_xy_left_attrs,
-+};
-+
-+static struct attribute *gamepad_axis_xy_right_attrs[] = {
-+ &dev_attr_xpad_axis_xy_right_deadzone.attr,
-+ &dev_attr_axis_xyz_deadzone_index.attr,
-+ &dev_attr_xpad_axis_xy_right_ADZ.attr,
-+ &dev_attr_xpad_axis_xy_right_cal_reset.attr,
-+ &dev_attr_xpad_axis_xy_right_cal.attr,
-+ &dev_attr_xpad_axis_xy_cal_index.attr,
-+ &dev_attr_rc_point_right_1.attr,
-+ &dev_attr_rc_point_right_2.attr,
-+ &dev_attr_rc_point_right_3.attr,
-+ &dev_attr_rc_point_right_4.attr,
-+ &dev_attr_rc_point_index.attr,
-+ NULL
-+};
-+static const struct attribute_group ally_controller_axis_xy_right_attr_group = {
-+ .name = "axis_xy_right",
-+ .attrs = gamepad_axis_xy_right_attrs,
-+};
-+
-+static struct attribute *gamepad_axis_z_left_attrs[] = {
-+ &dev_attr_xpad_axis_z_left_deadzone.attr, &dev_attr_axis_xyz_deadzone_index.attr,
-+ &dev_attr_xpad_axis_z_left_cal.attr, &dev_attr_xpad_axis_z_cal_index.attr,
-+ &dev_attr_xpad_axis_z_left_cal_reset.attr, NULL
-+};
-+static const struct attribute_group ally_controller_axis_z_left_attr_group = {
-+ .name = "axis_z_left",
-+ .attrs = gamepad_axis_z_left_attrs,
-+};
-+
-+static struct attribute *gamepad_axis_z_right_attrs[] = {
-+ &dev_attr_xpad_axis_z_right_deadzone.attr, &dev_attr_axis_xyz_deadzone_index.attr,
-+ &dev_attr_xpad_axis_z_right_cal.attr, &dev_attr_xpad_axis_z_cal_index.attr,
-+ &dev_attr_xpad_axis_z_right_cal_reset.attr, NULL
-+};
-+static const struct attribute_group ally_controller_axis_z_right_attr_group = {
-+ .name = "axis_z_right",
-+ .attrs = gamepad_axis_z_right_attrs,
-+};
-+
-+static const struct attribute_group *gamepad_device_attr_groups[] = {
-+ &ally_controller_attr_group,
-+ &ally_controller_axis_xy_left_attr_group,
-+ &ally_controller_axis_xy_right_attr_group,
-+ &ally_controller_axis_z_left_attr_group,
-+ &ally_controller_axis_z_right_attr_group,
-+ &btn_mapping_m1_attr_group,
-+ &btn_mapping_m2_attr_group,
-+ &btn_mapping_a_attr_group,
-+ &btn_mapping_b_attr_group,
-+ &btn_mapping_x_attr_group,
-+ &btn_mapping_y_attr_group,
-+ &btn_mapping_lb_attr_group,
-+ &btn_mapping_rb_attr_group,
-+ &btn_mapping_ls_attr_group,
-+ &btn_mapping_rs_attr_group,
-+ &btn_mapping_dpad_u_attr_group,
-+ &btn_mapping_dpad_d_attr_group,
-+ &btn_mapping_dpad_l_attr_group,
-+ &btn_mapping_dpad_r_attr_group,
-+ &btn_mapping_view_attr_group,
-+ &btn_mapping_menu_attr_group,
-+ NULL
-+};
-+
-+static int __gamepad_write_all_to_mcu(struct hid_device *hdev,
-+ struct ally_gamepad_cfg *ally_cfg)
-+{
-+ u8 *hidbuf;
-+ int ret;
-+
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_dpad_u_d);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_dpad_l_r);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_ls_rs);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_lb_rb);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_a_b);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_x_y);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_view_menu);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_set_mapping(hdev, ally_cfg, btn_pair_m1_m2);
-+ if (ret < 0)
-+ return ret;
-+ __gamepad_set_mapping(hdev, ally_cfg, btn_pair_lt_rt);
-+ if (ret < 0)
-+ return ret;
-+ __gamepad_set_deadzones(hdev, ally_cfg);
-+ if (ret < 0)
-+ return ret;
-+ __gamepad_write_js_ADZ_to_mcu(hdev, ally_cfg);
-+ if (ret < 0)
-+ return ret;
-+ __gamepad_write_vibe_intensity_to_mcu(hdev, ally_cfg);
-+ if (ret < 0)
-+ return ret;
-+ __gamepad_write_response_curves_to_mcu(hdev, ally_cfg);
-+ if (ret < 0)
-+ return ret;
-+ ret = __gamepad_check_ready(hdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* set turbo */
-+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
-+ if (!hidbuf)
-+ return -ENOMEM;
-+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
-+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
-+ hidbuf[2] = xpad_cmd_set_turbo;
-+ hidbuf[3] = xpad_cmd_len_turbo;
-+ memcpy(&hidbuf[4], ally_cfg->turbo_btns[ally_cfg->mode - 1], TURBO_BLOCK_LEN);
-+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
-+
-+ kfree(hidbuf);
-+ return ret;
-+}
-+
-+static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
-+{
-+ struct ally_gamepad_cfg *ally_cfg;
-+ struct input_dev *input_dev;
-+ int i, err;
-+
-+ ally_cfg = devm_kzalloc(&hdev->dev, sizeof(*ally_cfg), GFP_KERNEL);
-+ if (!ally_cfg)
-+ return ERR_PTR(-ENOMEM);
-+ ally_cfg->hdev = hdev;
-+
-+ input_dev = devm_input_allocate_device(&hdev->dev);
-+ if (!input_dev) {
-+ err = -ENOMEM;
-+ goto free_ally_cfg;
-+ }
-+ ally_cfg->input = input_dev;
-+
-+ input_dev->id.bustype = hdev->bus;
-+ input_dev->id.vendor = hdev->vendor;
-+ input_dev->id.product = hdev->product;
-+ input_dev->id.version = hdev->version;
-+ input_dev->uniq = hdev->uniq;
-+ input_dev->name = "ASUS ROG Ally Config";
-+ input_set_capability(input_dev, EV_KEY, KEY_PROG1);
-+ input_set_capability(input_dev, EV_KEY, KEY_F16);
-+ input_set_capability(input_dev, EV_KEY, KEY_F17);
-+ input_set_capability(input_dev, EV_KEY, KEY_F18);
-+
-+ input_set_drvdata(input_dev, hdev);
-+
-+ err = input_register_device(input_dev);
-+ if (err)
-+ goto free_input_dev;
-+
-+ ally_cfg->mode = xpad_mode_game;
-+ for (i = 0; i < xpad_mode_mouse; i++) {
-+ ally_cfg->deadzones[i][0][1] = 64;
-+ ally_cfg->deadzones[i][0][3] = 64;
-+ ally_cfg->deadzones[i][1][1] = 64;
-+ ally_cfg->deadzones[i][1][3] = 64;
-+ ally_cfg->response_curve[i][0][0] = 0x14;
-+ ally_cfg->response_curve[i][0][1] = 0x14;
-+ ally_cfg->response_curve[i][0][2] = 0x28;
-+ ally_cfg->response_curve[i][0][3] = 0x28;
-+ ally_cfg->response_curve[i][0][4] = 0x3c;
-+ ally_cfg->response_curve[i][0][5] = 0x3c;
-+ ally_cfg->response_curve[i][0][6] = 0x63;
-+ ally_cfg->response_curve[i][0][7] = 0x63;
-+ ally_cfg->response_curve[i][1][0] = 0x14;
-+ ally_cfg->response_curve[i][1][1] = 0x14;
-+ ally_cfg->response_curve[i][1][2] = 0x28;
-+ ally_cfg->response_curve[i][1][3] = 0x28;
-+ ally_cfg->response_curve[i][1][4] = 0x3c;
-+ ally_cfg->response_curve[i][1][5] = 0x3c;
-+ ally_cfg->response_curve[i][1][6] = 0x63;
-+ ally_cfg->response_curve[i][1][7] = 0x63;
-+ ally_cfg->vibration_intensity[i][0] = 64;
-+ ally_cfg->vibration_intensity[i][1] = 64;
-+ }
-+ drvdata.gamepad_cfg = ally_cfg;
-+
-+ /* ignore all errors for this as they are related to USB HID I/O */
-+ __gamepad_mapping_xpad_default(ally_cfg);
-+ __gamepad_mapping_wasd_default(ally_cfg);
-+ /* these calls will never error so ignore the return */
-+ __gamepad_mapping_store(ally_cfg, KB_M2, btn_pair_m1_m2, btn_pair_side_left, false);
-+ __gamepad_mapping_store(ally_cfg, KB_M1, btn_pair_m1_m2, btn_pair_side_right, false);
-+ __gamepad_set_mode(hdev, ally_cfg, xpad_mode_game);
-+ __gamepad_set_mapping(hdev, ally_cfg, btn_pair_m1_m2);
-+ /* ensure we have data for users to start from */
-+ __gamepad_get_calibration(hdev);
-+
-+ if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {
-+ err = -ENODEV;
-+ goto unregister_input_dev;
-+ }
-+
-+ return ally_cfg;
-+
-+unregister_input_dev:
-+ input_unregister_device(input_dev);
-+ ally_cfg->input = NULL; // Prevent double free when kfree(ally_cfg) happens
-+
-+free_input_dev:
-+ devm_kfree(&hdev->dev, input_dev);
-+
-+free_ally_cfg:
-+ devm_kfree(&hdev->dev, ally_cfg);
-+ return ERR_PTR(err);
-+}
-+
-+static void ally_cfg_remove(struct hid_device *hdev)
-+{
-+ __gamepad_set_mode(hdev, drvdata.gamepad_cfg, xpad_mode_mouse);
-+ sysfs_remove_groups(&hdev->dev.kobj, gamepad_device_attr_groups);
-+}
-+
-+/**************************************************************************************************/
-+/* ROG Ally LED control */
-+/**************************************************************************************************/
-+static void ally_schedule_work(struct ally_rgb_leds *led)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&led->lock, flags);
-+ if (!led->removed)
-+ schedule_work(&led->work);
-+ spin_unlock_irqrestore(&led->lock, flags);
-+}
-+
-+static void ally_led_do_brightness(struct work_struct *work)
-+{
-+ struct ally_rgb_leds *led = container_of(work, struct ally_rgb_leds, work);
-+ u8 buf[] = { FEATURE_ROG_ALLY_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 };
-+ unsigned long flags;
-+ bool do_rgb = false;
-+
-+ spin_lock_irqsave(&led->lock, flags);
-+ if (!led->update_bright) {
-+ spin_unlock_irqrestore(&led->lock, flags);
-+ return;
-+ }
-+ led->update_bright = false;
-+ do_rgb = led->rgb_software_mode;
-+ buf[4] = led->brightness;
-+ spin_unlock_irqrestore(&led->lock, flags);
-+
-+ if (asus_dev_set_report(led->hdev, buf, sizeof(buf)) < 0)
-+ hid_err(led->hdev, "Ally failed to set backlight\n");
-+
-+ if (do_rgb) {
-+ led->update_rgb = true;
-+ ally_schedule_work(led);
-+ }
-+}
-+
-+static void ally_led_do_rgb(struct work_struct *work)
-+{
-+ struct ally_rgb_leds *led = container_of(work, struct ally_rgb_leds, work);
-+ unsigned long flags;
-+ int ret;
-+
-+ u8 buf[16] = { [0] = FEATURE_ROG_ALLY_REPORT_ID,
-+ [1] = FEATURE_ROG_ALLY_CODE_PAGE,
-+ [2] = xpad_cmd_set_leds,
-+ [3] = xpad_cmd_len_leds };
-+
-+ spin_lock_irqsave(&led->lock, flags);
-+ if (!led->update_rgb) {
-+ spin_unlock_irqrestore(&led->lock, flags);
-+ return;
-+ }
-+ for (int i = 0; i < 4; i++) {
-+ buf[4 + i * 3] = led->gamepad_red[i];
-+ buf[5 + i * 3] = led->gamepad_green[i];
-+ buf[6 + i * 3] = led->gamepad_blue[i];
-+ }
-+ led->update_rgb = false;
-+ spin_unlock_irqrestore(&led->lock, flags);
-+
-+ ret = asus_dev_set_report(led->hdev, buf, sizeof(buf));
-+ if (ret < 0)
-+ hid_err(led->hdev, "Ally failed to set gamepad backlight: %d\n", ret);
-+}
-+
-+static void ally_led_work(struct work_struct *work)
-+{
-+ ally_led_do_brightness(work);
-+ ally_led_do_rgb(work);
-+}
-+
-+static void ally_backlight_set(struct led_classdev *led_cdev, enum led_brightness brightness)
-+{
-+ struct ally_rgb_leds *led =
-+ container_of(led_cdev, struct ally_rgb_leds, led_bright_dev);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&led->lock, flags);
-+ led->update_bright = true;
-+ led->brightness = brightness;
-+ spin_unlock_irqrestore(&led->lock, flags);
-+
-+ ally_schedule_work(led);
-+}
-+
-+static enum led_brightness ally_backlight_get(struct led_classdev *led_cdev)
-+{
-+ struct ally_rgb_leds *led =
-+ container_of(led_cdev, struct ally_rgb_leds, led_bright_dev);
-+ enum led_brightness brightness;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&led->lock, flags);
-+ brightness = led->brightness;
-+ spin_unlock_irqrestore(&led->lock, flags);
-+
-+ return brightness;
-+}
-+
-+static void ally_set_rgb_brightness(struct led_classdev *cdev, enum led_brightness brightness)
-+{
-+ struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
-+ struct ally_rgb_leds *led = container_of(mc_cdev, struct ally_rgb_leds, led_rgb_dev);
-+ unsigned long flags;
-+
-+ led_mc_calc_color_components(mc_cdev, brightness);
-+ spin_lock_irqsave(&led->lock, flags);
-+ led->update_rgb = true;
-+ led->rgb_software_mode = true;
-+ for (int i = 0; i < 4; i++) {
-+ led->gamepad_red[i] = mc_cdev->subled_info[i * 3].brightness;
-+ led->gamepad_green[i] = mc_cdev->subled_info[i * 3 + 1].brightness;
-+ led->gamepad_blue[i] = mc_cdev->subled_info[i * 3 + 2].brightness;
-+ }
-+ spin_unlock_irqrestore(&led->lock, flags);
-+
-+ ally_schedule_work(led);
-+}
-+
-+static int ally_gamepad_register_brightness(struct hid_device *hdev,
-+ struct ally_rgb_leds *led_rgb)
-+{
-+ struct led_classdev *led_cdev;
-+
-+ led_cdev = &led_rgb->led_bright_dev;
-+ led_cdev->name = "asus::kbd_backlight"; /* Let a desktop control it also */
-+ led_cdev->max_brightness = 3;
-+ led_cdev->brightness_set = ally_backlight_set;
-+ led_cdev->brightness_get = ally_backlight_get;
-+
-+ return devm_led_classdev_register(&hdev->dev, &led_rgb->led_bright_dev);
-+}
-+
-+static int ally_gamepad_register_rgb_leds(struct hid_device *hdev,
-+ struct ally_rgb_leds *led_rgb)
-+{
-+ struct mc_subled *mc_led_info;
-+ struct led_classdev *led_cdev;
-+
-+ mc_led_info = devm_kmalloc_array(&hdev->dev, 12, sizeof(*mc_led_info),
-+ GFP_KERNEL | __GFP_ZERO);
-+ if (!mc_led_info)
-+ return -ENOMEM;
-+
-+ mc_led_info[0].color_index = LED_COLOR_ID_RED;
-+ mc_led_info[1].color_index = LED_COLOR_ID_GREEN;
-+ mc_led_info[2].color_index = LED_COLOR_ID_BLUE;
-+
-+ mc_led_info[3].color_index = LED_COLOR_ID_RED;
-+ mc_led_info[4].color_index = LED_COLOR_ID_GREEN;
-+ mc_led_info[5].color_index = LED_COLOR_ID_BLUE;
-+
-+ mc_led_info[6].color_index = LED_COLOR_ID_RED;
-+ mc_led_info[7].color_index = LED_COLOR_ID_GREEN;
-+ mc_led_info[8].color_index = LED_COLOR_ID_BLUE;
-+
-+ mc_led_info[9].color_index = LED_COLOR_ID_RED;
-+ mc_led_info[10].color_index = LED_COLOR_ID_GREEN;
-+ mc_led_info[11].color_index = LED_COLOR_ID_BLUE;
-+
-+ led_rgb->led_rgb_dev.subled_info = mc_led_info;
-+ led_rgb->led_rgb_dev.num_colors = 3 * 4;
-+
-+ led_cdev = &led_rgb->led_rgb_dev.led_cdev;
-+ led_cdev->name = "ally:rgb:joystick_rings";
-+ led_cdev->brightness = 128;
-+ led_cdev->max_brightness = 255;
-+ led_cdev->brightness_set = ally_set_rgb_brightness;
-+
-+ return devm_led_classdev_multicolor_register(&hdev->dev, &led_rgb->led_rgb_dev);
-+}
-+
-+static struct ally_rgb_leds *ally_gamepad_rgb_create(struct hid_device *hdev)
-+{
-+ struct ally_rgb_leds *led_rgb;
-+ int ret;
-+
-+ led_rgb = devm_kzalloc(&hdev->dev, sizeof(struct ally_rgb_leds), GFP_KERNEL);
-+ if (!led_rgb)
-+ return ERR_PTR(-ENOMEM);
-+
-+ ret = ally_gamepad_register_rgb_leds(hdev, led_rgb);
-+ if (ret < 0) {
-+ cancel_work_sync(&led_rgb->work);
-+ devm_kfree(&hdev->dev, led_rgb);
-+ return ERR_PTR(ret);
-+ }
-+
-+ ret = ally_gamepad_register_brightness(hdev, led_rgb);
-+ if (ret < 0) {
-+ cancel_work_sync(&led_rgb->work);
-+ devm_kfree(&hdev->dev, led_rgb);
-+ return ERR_PTR(ret);
-+ }
-+
-+ led_rgb->hdev = hdev;
-+ led_rgb->brightness = 3;
-+ led_rgb->removed = false;
-+
-+ for (int i = 0; i < 4; i++) {
-+ led_rgb->gamepad_red[i] = 255;
-+ led_rgb->gamepad_green[i] = 255;
-+ led_rgb->gamepad_blue[i] = 255;
-+ }
-+
-+ INIT_WORK(&led_rgb->work, ally_led_work);
-+ spin_lock_init(&led_rgb->lock);
-+
-+ led_rgb->update_bright = true;
-+ ally_schedule_work(led_rgb);
-+
-+ return led_rgb;
-+}
-+
-+static void ally_rgb_remove(struct hid_device *hdev)
-+{
-+ struct ally_rgb_leds *led_rgb = drvdata.led_rgb;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&led_rgb->lock, flags);
-+ led_rgb->removed = true;
-+ spin_unlock_irqrestore(&led_rgb->lock, flags);
-+ cancel_work_sync(&led_rgb->work);
-+}
-+
-+/**************************************************************************************************/
-+/* ROG Ally driver init */
-+/**************************************************************************************************/
-+static int ally_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data,
-+ int size)
-+{
-+ struct ally_gamepad_cfg *cfg = drvdata.gamepad_cfg;
-+ struct ally_x_device *ally_x = drvdata.ally_x;
-+
-+ if (ally_x) {
-+ if ((hdev->bus == BUS_USB && report->id == ALLY_X_INPUT_REPORT_USB &&
-+ size == ALLY_X_INPUT_REPORT_USB_SIZE) ||
-+ (cfg && data[0] == 0x5A)) {
-+ ally_x_raw_event(ally_x, report, data, size);
-+ } else {
-+ return -1;
-+ }
-+ }
-+ if (cfg && !ally_x) {
-+ input_report_key(cfg->input, KEY_PROG1, data[1] == 0x38);
-+ input_report_key(cfg->input, KEY_F16, data[1] == 0xA6);
-+ input_report_key(cfg->input, KEY_F17, data[1] == 0xA7);
-+ input_report_key(cfg->input, KEY_F18, data[1] == 0xA8);
-+ input_sync(cfg->input);
-+ }
-+
-+ return 0;
-+}
-+
-+static int ally_gamepad_init(struct hid_device *hdev, u8 report_id)
-+{
-+ const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, 0x65,
-+ 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
-+ int ret;
-+
-+ ret = asus_dev_set_report(hdev, buf, sizeof(buf));
-+ if (ret < 0)
-+ hid_err(hdev, "Ally failed to send init command: %d\n", ret);
-+
-+ return ret;
-+}
-+
-+static int ally_probe(struct hid_device *hdev, const struct hid_device_id *id)
-+{
-+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
-+ struct usb_host_endpoint *ep = intf->cur_altsetting->endpoint;
-+ int ret;
-+
-+ if (ep->desc.bEndpointAddress != ALLY_CFG_INTF_IN_ADDRESS &&
-+ ep->desc.bEndpointAddress != ALLY_X_INTERFACE_ADDRESS)
-+ return -ENODEV;
-+
-+ ret = hid_parse(hdev);
-+ if (ret) {
-+ hid_err(hdev, "Parse failed\n");
-+ return ret;
-+ }
-+
-+ ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
-+ if (ret) {
-+ hid_err(hdev, "Failed to start HID device\n");
-+ return ret;
-+ }
-+
-+ ret = hid_hw_open(hdev);
-+ if (ret) {
-+ hid_err(hdev, "Failed to open HID device\n");
-+ goto err_stop;
-+ }
-+
-+ /* Initialize MCU even before alloc */
-+ ret = ally_gamepad_init(hdev, FEATURE_REPORT_ID);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ally_gamepad_init(hdev, FEATURE_KBD_LED_REPORT_ID1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ally_gamepad_init(hdev, FEATURE_KBD_LED_REPORT_ID2);
-+ if (ret < 0)
-+ return ret;
-+
-+ drvdata.hdev = hdev;
-+ hid_set_drvdata(hdev, &drvdata);
-+
-+ /* This should almost always exist */
-+ if (ep->desc.bEndpointAddress == ALLY_CFG_INTF_IN_ADDRESS) {
-+ drvdata.led_rgb = ally_gamepad_rgb_create(hdev);
-+ if (IS_ERR(drvdata.led_rgb))
-+ hid_err(hdev, "Failed to create Ally gamepad LEDs.\n");
-+ else
-+ hid_info(hdev, "Created Ally RGB LED controls.\n");
-+
-+ ally_gamepad_cfg_create(hdev); // assigns self
-+ if (IS_ERR(drvdata.gamepad_cfg))
-+ hid_err(hdev, "Failed to create Ally gamepad attributes.\n");
-+ else
-+ hid_info(hdev, "Created Ally gamepad attributes.\n");
-+
-+ if (IS_ERR(drvdata.led_rgb) && IS_ERR(drvdata.gamepad_cfg))
-+ goto err_close;
-+ }
-+
-+ /* May or may not exist */
-+ if (ep->desc.bEndpointAddress == ALLY_X_INTERFACE_ADDRESS) {
-+ drvdata.ally_x = ally_x_create(hdev);
-+ if (IS_ERR(drvdata.ally_x)) {
-+ hid_err(hdev, "Failed to create Ally X gamepad.\n");
-+ drvdata.ally_x = NULL;
-+ goto err_close;
-+ }
-+ hid_info(hdev, "Created Ally X controller.\n");
-+
-+ // Not required since we send this inputs ep through the gamepad input dev
-+ if (drvdata.gamepad_cfg && drvdata.gamepad_cfg->input) {
-+ input_unregister_device(drvdata.gamepad_cfg->input);
-+ hid_info(hdev, "Ally X removed unrequired input dev.\n");
-+ }
-+ }
-+
-+ return 0;
-+
-+err_close:
-+ hid_hw_close(hdev);
-+err_stop:
-+ hid_hw_stop(hdev);
-+ return ret;
-+}
-+
-+static void ally_remove(struct hid_device *hdev)
-+{
-+ if (drvdata.ally_x)
-+ ally_x_remove(hdev);
-+ if (drvdata.led_rgb)
-+ ally_rgb_remove(hdev);
-+ if (drvdata.gamepad_cfg)
-+ ally_cfg_remove(hdev);
-+ hid_hw_close(hdev);
-+ hid_hw_stop(hdev);
-+}
-+
-+static int ally_resume(struct hid_device *hdev)
-+{
-+ int ret;
-+
-+ ret = ally_gamepad_init(hdev, FEATURE_REPORT_ID);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ally_gamepad_init(hdev, FEATURE_KBD_LED_REPORT_ID1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ally_gamepad_init(hdev, FEATURE_KBD_LED_REPORT_ID2);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (drvdata.ally_x && drvdata.ally_x->output_worker_initialized) {
-+ drvdata.ally_x->update_ff = true;
-+ schedule_work(&drvdata.ally_x->output_worker);
-+ }
-+
-+ return ret;
-+}
-+
-+MODULE_DEVICE_TABLE(hid, rog_ally_devices);
-+
-+static struct hid_driver rog_ally_cfg = {
-+ .name = "asus_rog_ally",
-+ .id_table = rog_ally_devices,
-+ .probe = ally_probe,
-+ .remove = ally_remove,
-+ .raw_event = ally_raw_event,
-+ .resume = ally_resume,
-+ .reset_resume = ally_resume,
-+};
-+
-+static int __init rog_ally_cfg_init(void)
-+{
-+ return hid_register_driver(&rog_ally_cfg);
-+}
-+
-+static void __exit rog_ally_cfg_exit(void)
-+{
-+ hid_unregister_driver(&rog_ally_cfg);
-+}
-+
-+module_init(rog_ally_cfg_init);
-+module_exit(rog_ally_cfg_exit);
-+
-+MODULE_AUTHOR("Luke D. Jones");
-+MODULE_DESCRIPTION("HID Driver for ASUS ROG Ally gamepad configuration.");
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
-new file mode 100644
-index 000000000000..252d9f126e32
---- /dev/null
-+++ b/drivers/hid/hid-asus-ally.h
-@@ -0,0 +1,544 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later
-+ *
-+ * HID driver for Asus ROG laptops and Ally
-+ *
-+ * Copyright (c) 2023 Luke Jones
-+ */
-+
-+#include
-+#include
-+
-+#define ALLY_X_INTERFACE_ADDRESS 0x87
-+
-+#define BTN_CODE_LEN 11
-+#define MAPPING_BLOCK_LEN 44
-+
-+#define TURBO_BLOCK_LEN 32
-+#define TURBO_BLOCK_STEP 2
-+
-+#define PAD_A "pad_a"
-+#define PAD_B "pad_b"
-+#define PAD_X "pad_x"
-+#define PAD_Y "pad_y"
-+#define PAD_LB "pad_lb"
-+#define PAD_RB "pad_rb"
-+#define PAD_LS "pad_ls"
-+#define PAD_RS "pad_rs"
-+#define PAD_DPAD_UP "pad_dpad_up"
-+#define PAD_DPAD_DOWN "pad_dpad_down"
-+#define PAD_DPAD_LEFT "pad_dpad_left"
-+#define PAD_DPAD_RIGHT "pad_dpad_right"
-+#define PAD_VIEW "pad_view"
-+#define PAD_MENU "pad_menu"
-+#define PAD_XBOX "pad_xbox"
-+
-+#define KB_M1 "kb_m1"
-+#define KB_M2 "kb_m2"
-+#define KB_ESC "kb_esc"
-+#define KB_F1 "kb_f1"
-+#define KB_F2 "kb_f2"
-+#define KB_F3 "kb_f3"
-+#define KB_F4 "kb_f4"
-+#define KB_F5 "kb_f5"
-+#define KB_F6 "kb_f6"
-+#define KB_F7 "kb_f7"
-+#define KB_F8 "kb_f8"
-+#define KB_F9 "kb_f9"
-+#define KB_F10 "kb_f10"
-+#define KB_F11 "kb_f11"
-+#define KB_F12 "kb_f12"
-+#define KB_F14 "kb_f14"
-+#define KB_F15 "kb_f15"
-+
-+#define KB_BACKTICK "kb_backtick"
-+#define KB_1 "kb_1"
-+#define KB_2 "kb_2"
-+#define KB_3 "kb_3"
-+#define KB_4 "kb_4"
-+#define KB_5 "kb_5"
-+#define KB_6 "kb_6"
-+#define KB_7 "kb_7"
-+#define KB_8 "kb_8"
-+#define KB_9 "kb_9"
-+#define KB_0 "kb_0"
-+#define KB_HYPHEN "kb_hyphen"
-+#define KB_EQUALS "kb_equals"
-+#define KB_BACKSPACE "kb_backspace"
-+
-+#define KB_TAB "kb_tab"
-+#define KB_Q "kb_q"
-+#define KB_W "kb_w"
-+#define KB_E "kb_e"
-+#define KB_R "kb_r"
-+#define KB_T "kb_t"
-+#define KB_Y "kb_y"
-+#define KB_U "kb_u"
-+#define KB_I "kb_i"
-+#define KB_O "kb_o"
-+#define KB_P "kb_p"
-+#define KB_LBRACKET "kb_lbracket"
-+#define KB_RBRACKET "kb_rbracket"
-+#define KB_BACKSLASH "kb_bkslash"
-+
-+#define KB_CAPS "kb_caps"
-+#define KB_A "kb_a"
-+#define KB_S "kb_s"
-+#define KB_D "kb_d"
-+#define KB_F "kb_f"
-+#define KB_G "kb_g"
-+#define KB_H "kb_h"
-+#define KB_J "kb_j"
-+#define KB_K "kb_k"
-+#define KB_L "kb_l"
-+#define KB_SEMI "kb_semicolon"
-+#define KB_QUOTE "kb_quote"
-+#define KB_RET "kb_enter"
-+
-+#define KB_LSHIFT "kb_lshift"
-+#define KB_Z "kb_z"
-+#define KB_X "kb_x"
-+#define KB_C "kb_c"
-+#define KB_V "kb_v"
-+#define KB_B "kb_b"
-+#define KB_N "kb_n"
-+#define KB_M "kb_m"
-+#define KB_COMMA "kb_comma"
-+#define KB_PERIOD "kb_period"
-+#define KB_FWDSLASH "kb_fwdslash"
-+#define KB_RSHIFT "kb_rshift"
-+
-+#define KB_LCTL "kb_lctl"
-+#define KB_META "kb_meta"
-+#define KB_LALT "kb_lalt"
-+#define KB_SPACE "kb_space"
-+#define KB_RALT "kb_ralt"
-+#define KB_MENU "kb_menu"
-+#define KB_RCTL "kb_rctl"
-+
-+#define KB_PRNTSCN "kb_prntscn"
-+#define KB_SCRLCK "kb_scrlck"
-+#define KB_PAUSE "kb_pause"
-+#define KB_INS "kb_ins"
-+#define KB_HOME "kb_home"
-+#define KB_PGUP "kb_pgup"
-+#define KB_DEL "kb_del"
-+#define KB_END "kb_end"
-+#define KB_PGDWN "kb_pgdwn"
-+
-+#define KB_UP_ARROW "kb_up_arrow"
-+#define KB_DOWN_ARROW "kb_down_arrow"
-+#define KB_LEFT_ARROW "kb_left_arrow"
-+#define KB_RIGHT_ARROW "kb_right_arrow"
-+
-+#define NUMPAD_LOCK "numpad_lock"
-+#define NUMPAD_FWDSLASH "numpad_fwdslash"
-+#define NUMPAD_ASTERISK "numpad_asterisk"
-+#define NUMPAD_HYPHEN "numpad_hyphen"
-+#define NUMPAD_0 "numpad_0"
-+#define NUMPAD_1 "numpad_1"
-+#define NUMPAD_2 "numpad_2"
-+#define NUMPAD_3 "numpad_3"
-+#define NUMPAD_4 "numpad_4"
-+#define NUMPAD_5 "numpad_5"
-+#define NUMPAD_6 "numpad_6"
-+#define NUMPAD_7 "numpad_7"
-+#define NUMPAD_8 "numpad_8"
-+#define NUMPAD_9 "numpad_9"
-+#define NUMPAD_PLUS "numpad_plus"
-+#define NUMPAD_ENTER "numpad_enter"
-+#define NUMPAD_PERIOD "numpad_."
-+
-+#define MOUSE_LCLICK "rat_lclick"
-+#define MOUSE_RCLICK "rat_rclick"
-+#define MOUSE_MCLICK "rat_mclick"
-+#define MOUSE_WHEEL_UP "rat_wheel_up"
-+#define MOUSE_WHEEL_DOWN "rat_wheel_down"
-+
-+#define MEDIA_SCREENSHOT "media_screenshot"
-+#define MEDIA_SHOW_KEYBOARD "media_show_keyboard"
-+#define MEDIA_SHOW_DESKTOP "media_show_desktop"
-+#define MEDIA_START_RECORDING "media_start_recording"
-+#define MEDIA_MIC_OFF "media_mic_off"
-+#define MEDIA_VOL_DOWN "media_vol_down"
-+#define MEDIA_VOL_UP "media_vol_up"
-+
-+/* required so we can have nested attributes with same name but different functions */
-+#define ALLY_DEVICE_ATTR_RW(_name, _sysfs_name) \
-+ struct device_attribute dev_attr_##_name = \
-+ __ATTR(_sysfs_name, 0644, _name##_show, _name##_store)
-+
-+#define ALLY_DEVICE_ATTR_RO(_name, _sysfs_name) \
-+ struct device_attribute dev_attr_##_name = \
-+ __ATTR(_sysfs_name, 0444, _name##_show, NULL)
-+
-+#define ALLY_DEVICE_ATTR_WO(_name, _sysfs_name) \
-+ struct device_attribute dev_attr_##_name = \
-+ __ATTR(_sysfs_name, 0200, NULL, _name##_store)
-+
-+/* response curve macros */
-+#define ALLY_RESP_CURVE_SHOW(_name, _point_n) \
-+ static ssize_t _name##_show(struct device *dev, \
-+ struct device_attribute *attr, char *buf) \
-+ { \
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
-+ int idx = (_point_n - 1) * 2; \
-+ if (!drvdata.gamepad_cfg) \
-+ return -ENODEV; \
-+ return sysfs_emit( \
-+ buf, "%d %d\n", \
-+ ally_cfg->response_curve[ally_cfg->mode] \
-+ [btn_pair_side_left][idx], \
-+ ally_cfg->response_curve[ally_cfg->mode] \
-+ [btn_pair_side_right] \
-+ [idx + 1]); \
-+ }
-+
-+#define ALLY_RESP_CURVE_STORE(_name, _side, _point_n) \
-+ static ssize_t _name##_store(struct device *dev, \
-+ struct device_attribute *attr, \
-+ const char *buf, size_t count) \
-+ { \
-+ int ret = __gamepad_store_response_curve( \
-+ dev, buf, btn_pair_side_##_side, _point_n); \
-+ if (ret < 0) \
-+ return ret; \
-+ return count; \
-+ }
-+
-+/* _point_n must start at 1 */
-+#define ALLY_JS_RC_POINT(_side, _point_n, _sysfs_label) \
-+ ALLY_RESP_CURVE_SHOW(rc_point_##_side##_##_point_n, _point_n); \
-+ ALLY_RESP_CURVE_STORE(rc_point_##_side##_##_point_n, _side, _point_n); \
-+ ALLY_DEVICE_ATTR_RW(rc_point_##_side##_##_point_n, \
-+ _sysfs_label##_point_n)
-+
-+/* deadzone macros */
-+#define ALLY_AXIS_DEADZONE_SHOW(_axis) \
-+ static ssize_t _axis##_deadzone_show( \
-+ struct device *dev, struct device_attribute *attr, char *buf) \
-+ { \
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
-+ int side, is_tr; \
-+ if (!drvdata.gamepad_cfg) \
-+ return -ENODEV; \
-+ is_tr = _axis > xpad_axis_xy_right; \
-+ side = _axis == xpad_axis_xy_right || \
-+ _axis == xpad_axis_z_right ? \
-+ 2 : \
-+ 0; \
-+ return sysfs_emit( \
-+ buf, "%d %d\n", \
-+ ally_cfg->deadzones[ally_cfg->mode][is_tr][side], \
-+ ally_cfg->deadzones[ally_cfg->mode][is_tr][side + 1]); \
-+ }
-+
-+#define ALLY_AXIS_DEADZONE_STORE(_axis) \
-+ static ssize_t _axis##_deadzone_store(struct device *dev, \
-+ struct device_attribute *attr, \
-+ const char *buf, size_t count) \
-+ { \
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
-+ if (!drvdata.gamepad_cfg) \
-+ return -ENODEV; \
-+ int ret = __gamepad_store_deadzones(ally_cfg, _axis, buf); \
-+ if (ret < 0) \
-+ return ret; \
-+ return count; \
-+ }
-+
-+#define ALLY_AXIS_DEADZONE(_axis, _sysfs_label) \
-+ ALLY_AXIS_DEADZONE_SHOW(_axis); \
-+ ALLY_AXIS_DEADZONE_STORE(_axis); \
-+ ALLY_DEVICE_ATTR_RW(_axis##_deadzone, _sysfs_label)
-+
-+/* button specific macros */
-+#define ALLY_BTN_SHOW(_fname, _pair, _side, _secondary) \
-+ static ssize_t _fname##_show(struct device *dev, \
-+ struct device_attribute *attr, char *buf) \
-+ { \
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
-+ if (!drvdata.gamepad_cfg) \
-+ return -ENODEV; \
-+ return sysfs_emit(buf, "%s\n", \
-+ __btn_map_to_string(ally_cfg, _pair, _side, \
-+ _secondary)); \
-+ }
-+
-+#define ALLY_BTN_STORE(_fname, _pair, _side, _secondary) \
-+ static ssize_t _fname##_store(struct device *dev, \
-+ struct device_attribute *attr, \
-+ const char *buf, size_t count) \
-+ { \
-+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
-+ if (!drvdata.gamepad_cfg) \
-+ return -ENODEV; \
-+ int ret = __gamepad_mapping_store(ally_cfg, buf, _pair, _side, \
-+ _secondary); \
-+ if (ret < 0) \
-+ return ret; \
-+ return count; \
-+ }
-+
-+#define ALLY_BTN_TURBO_SHOW(_fname, _pair, _side) \
-+ static ssize_t _fname##_turbo_show( \
-+ struct device *dev, struct device_attribute *attr, char *buf) \
-+ { \
-+ return sysfs_emit(buf, "%d\n", \
-+ __gamepad_turbo_show(dev, _pair, _side)); \
-+ }
-+
-+#define ALLY_BTN_TURBO_STORE(_fname, _pair, _side) \
-+ static ssize_t _fname##_turbo_store(struct device *dev, \
-+ struct device_attribute *attr, \
-+ const char *buf, size_t count) \
-+ { \
-+ int ret = __gamepad_turbo_store(dev, buf, _pair, _side); \
-+ if (ret < 0) \
-+ return ret; \
-+ return count; \
-+ }
-+
-+#define ALLY_BTN_ATTRS_GROUP(_name, _fname) \
-+ static struct attribute *_fname##_attrs[] = { \
-+ &dev_attr_##_fname.attr, &dev_attr_##_fname##_macro.attr, \
-+ &dev_attr_##_fname##_turbo.attr, NULL \
-+ }; \
-+ static const struct attribute_group _fname##_attr_group = { \
-+ .name = __stringify(_name), \
-+ .attrs = _fname##_attrs, \
-+ }
-+
-+#define ALLY_BTN_MAPPING(_fname, _pair, _side) \
-+ ALLY_BTN_SHOW(btn_mapping_##_fname, _pair, _side, false); \
-+ ALLY_BTN_STORE(btn_mapping_##_fname, _pair, _side, false); \
-+ ALLY_BTN_SHOW(btn_mapping_##_fname##_macro, _pair, _side, true); \
-+ ALLY_BTN_STORE(btn_mapping_##_fname##_macro, _pair, _side, true); \
-+ ALLY_BTN_TURBO_SHOW(btn_mapping_##_fname, _pair, _side); \
-+ ALLY_BTN_TURBO_STORE(btn_mapping_##_fname, _pair, _side); \
-+ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname, remap); \
-+ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname##_macro, macro_remap); \
-+ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname##_turbo, turbo); \
-+ ALLY_BTN_ATTRS_GROUP(btn_##_fname, btn_mapping_##_fname)
-+
-+/* calibration macros */
-+#define ALLY_CAL_STORE(_fname, _axis) \
-+ static ssize_t _fname##_store(struct device *dev, \
-+ struct device_attribute *attr, \
-+ const char *buf, size_t count) \
-+ { \
-+ int ret = __gamepad_cal_store(dev, buf, _axis); \
-+ if (ret < 0) \
-+ return ret; \
-+ return count; \
-+ }
-+
-+#define ALLY_CAL_SHOW(_fname, _axis) \
-+ static ssize_t _fname##_show(struct device *dev, \
-+ struct device_attribute *attr, char *buf) \
-+ { \
-+ return __gamepad_cal_show(dev, buf, _axis); \
-+ }
-+
-+#define ALLY_CAL_ATTR(_fname, _axis, _sysfs_label) \
-+ ALLY_CAL_STORE(_fname, _axis); \
-+ ALLY_CAL_SHOW(_fname, _axis); \
-+ ALLY_DEVICE_ATTR_RW(_fname, _sysfs_label)
-+
-+#define ALLY_CAL_RESET_STORE(_fname, _axis) \
-+ static ssize_t _fname##_store(struct device *dev, \
-+ struct device_attribute *attr, \
-+ const char *buf, size_t count) \
-+ { \
-+ int ret = __gamepad_cal_reset(dev, buf, _axis); \
-+ if (ret < 0) \
-+ return ret; \
-+ return count; \
-+ }
-+
-+#define ALLY_CAL_RESET_ATTR(_fname, _axis, _sysfs_label) \
-+ ALLY_CAL_RESET_STORE(_fname, _axis); \
-+ ALLY_DEVICE_ATTR_WO(_fname, _sysfs_label)
-+
-+/*
-+ * The following blocks of packets exist to make setting a default boot config
-+ * easier. They were directly captured from setting the gamepad up.
-+ */
-+
-+/* Default blocks for the xpad mode */
-+static const u8 XPAD_DEF1[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF2[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF3[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF4[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF5[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF6[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF7[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF8[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 XPAD_DEF9[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+
-+/* default blocks for the wasd mode */
-+static const u8 WASD_DEF1[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF2[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF3[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF4[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF5[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF6[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF7[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF8[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+static const u8 WASD_DEF9[MAPPING_BLOCK_LEN] = {
-+ 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
-+};
-+
-+/*
-+ * the xpad_mode is used inside the mode setting packet and is used
-+ * for indexing (xpad_mode - 1)
-+ */
-+enum xpad_mode {
-+ xpad_mode_game = 0x01,
-+ xpad_mode_wasd = 0x02,
-+ xpad_mode_mouse = 0x03,
-+};
-+
-+/* the xpad_cmd determines which feature is set or queried */
-+enum xpad_cmd {
-+ xpad_cmd_set_mode = 0x01,
-+ xpad_cmd_set_mapping = 0x02,
-+ xpad_cmd_set_js_dz = 0x04, /* deadzones */
-+ xpad_cmd_set_tr_dz = 0x05, /* deadzones */
-+ xpad_cmd_set_vibe_intensity = 0x06,
-+ xpad_cmd_set_leds = 0x08,
-+ xpad_cmd_check_ready = 0x0A,
-+ xpad_cmd_set_calibration = 0x0D,
-+ xpad_cmd_set_turbo = 0x0F,
-+ xpad_cmd_set_response_curve = 0x13,
-+ xpad_cmd_set_adz = 0x18,
-+};
-+
-+/* the xpad_cmd determines which feature is set or queried */
-+enum xpad_cmd_len {
-+ xpad_cmd_len_mode = 0x01,
-+ xpad_cmd_len_mapping = 0x2c,
-+ xpad_cmd_len_deadzone = 0x04,
-+ xpad_cmd_len_vibe_intensity = 0x02,
-+ xpad_cmd_len_leds = 0x0C,
-+ xpad_cmd_len_calibration2 = 0x01,
-+ xpad_cmd_len_calibration3 = 0x01,
-+ xpad_cmd_len_turbo = 0x20,
-+ xpad_cmd_len_response_curve = 0x09,
-+ xpad_cmd_len_adz = 0x02,
-+};
-+
-+/*
-+ * the xpad_mode is used in various set and query HID packets and is
-+ * used for indexing (xpad_axis - 1)
-+ */
-+enum xpad_axis {
-+ xpad_axis_xy_left = 0x01,
-+ xpad_axis_xy_right = 0x02,
-+ xpad_axis_z_left = 0x03,
-+ xpad_axis_z_right = 0x04,
-+};
-+
-+enum btn_pair {
-+ btn_pair_dpad_u_d = 0x01,
-+ btn_pair_dpad_l_r = 0x02,
-+ btn_pair_ls_rs = 0x03,
-+ btn_pair_lb_rb = 0x04,
-+ btn_pair_a_b = 0x05,
-+ btn_pair_x_y = 0x06,
-+ btn_pair_view_menu = 0x07,
-+ btn_pair_m1_m2 = 0x08,
-+ btn_pair_lt_rt = 0x09,
-+};
-+
-+enum btn_pair_side {
-+ btn_pair_side_left = 0x00,
-+ btn_pair_side_right = 0x01,
-+};
-diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
-index 659cf9c96e26..528c210f9e8c 100644
---- a/drivers/hid/hid-asus.c
-+++ b/drivers/hid/hid-asus.c
-@@ -52,6 +52,10 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
- #define FEATURE_KBD_LED_REPORT_ID1 0x5d
- #define FEATURE_KBD_LED_REPORT_ID2 0x5e
-
-+#define ALLY_CFG_INTF_IN_ADDRESS 0x83
-+#define ALLY_CFG_INTF_OUT_ADDRESS 0x04
-+#define ALLY_X_INTERFACE_ADDRESS 0x87
-+
- #define SUPPORT_KBD_BACKLIGHT BIT(0)
-
- #define MAX_TOUCH_MAJOR 8
-@@ -84,6 +88,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
- #define QUIRK_MEDION_E1239T BIT(10)
- #define QUIRK_ROG_NKEY_KEYBOARD BIT(11)
- #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
-+#define QUIRK_ROG_ALLY_XPAD BIT(13)
-
- #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
- QUIRK_NO_INIT_REPORTS | \
-@@ -1003,6 +1008,17 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
-
- drvdata->quirks = id->driver_data;
-
-+ /* Ignore these endpoints as they will be used by other drivers */
-+ if (drvdata->quirks & QUIRK_ROG_ALLY_XPAD) {
-+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
-+ struct usb_host_endpoint *ep = intf->cur_altsetting->endpoint;
-+
-+ if (ep->desc.bEndpointAddress == ALLY_X_INTERFACE_ADDRESS ||
-+ ep->desc.bEndpointAddress == ALLY_CFG_INTF_IN_ADDRESS ||
-+ ep->desc.bEndpointAddress == ALLY_CFG_INTF_OUT_ADDRESS)
-+ return -ENODEV;
-+ }
-+
- /*
- * T90CHI's keyboard dock returns same ID values as T100CHI's dock.
- * Thus, identify T90CHI dock with product name string.
-@@ -1254,10 +1270,10 @@ static const struct hid_device_id asus_devices[] = {
- 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 },
-+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD},
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
- USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
-- QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
-+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD },
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
- USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
- QUIRK_ROG_CLAYMORE_II_KEYBOARD },
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0016-hid-asus-ally-initial-gamepad-configuration.patch b/packages/l/linux-current/files/patches/hardware/asus/0016-hid-asus-ally-initial-gamepad-configuration.patch
new file mode 100644
index 00000000000..00a22c3f30e
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0016-hid-asus-ally-initial-gamepad-configuration.patch
@@ -0,0 +1,408 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Wed, 2 Oct 2024 23:51:36 +1300
+Subject: [PATCH 16/27] hid-asus-ally: initial gamepad configuration
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 259 +++++++++++++++++++++++++++++++++---
+ drivers/hid/hid-asus-ally.h | 38 +++---
+ 2 files changed, 264 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 33d9ac0c6bd5..eed1bc84026d 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -6,11 +6,8 @@
+ */
+
+ #include "linux/device.h"
+-#include "linux/err.h"
+-#include "linux/kstrtox.h"
+ #include "linux/pm.h"
+ #include "linux/slab.h"
+-#include "linux/stddef.h"
+ #include
+ #include
+ #include
+@@ -38,6 +35,9 @@
+ #define ALLY_MIN_BIOS 319
+ #define ALLY_X_MIN_BIOS 313
+
++#define BTN_DATA_LEN 11;
++#define BTN_CODE_BYTES_LEN 8
++
+ static const u8 EC_INIT_STRING[] = { 0x5A, 'A', 'S', 'U', 'S', ' ', 'T', 'e','c', 'h', '.', 'I', 'n', 'c', '.', '\0' };
+ static const u8 EC_MODE_LED_APPLY[] = { 0x5A, 0xB4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ static const u8 EC_MODE_LED_SET[] = { 0x5A, 0xB5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+@@ -49,6 +49,58 @@ static const struct hid_device_id rog_ally_devices[] = {
+ {}
+ };
+
++struct btn_code_map {
++ u64 code;
++ const char *name;
++};
++
++/* byte_array must be >= 8 in length */
++static void btn_code_to_byte_array(u64 keycode, u8 *byte_array)
++{
++ /* Convert the u64 to bytes[8] */
++ for (int i = 0; i < 8; ++i) {
++ byte_array[i] = (keycode >> (56 - 8 * i)) & 0xFF;
++ }
++}
++
++struct btn_data {
++ u64 button;
++ u64 macro;
++};
++
++struct btn_mapping {
++ struct btn_data btn_a;
++ struct btn_data btn_b;
++ struct btn_data btn_x;
++ struct btn_data btn_y;
++ struct btn_data btn_lb;
++ struct btn_data btn_rb;
++ struct btn_data btn_ls;
++ struct btn_data btn_rs;
++ struct btn_data btn_lt;
++ struct btn_data btn_rt;
++ struct btn_data dpad_up;
++ struct btn_data dpad_down;
++ struct btn_data dpad_left;
++ struct btn_data dpad_right;
++ struct btn_data btn_view;
++ struct btn_data btn_menu;
++ struct btn_data btn_m1;
++ struct btn_data btn_m2;
++};
++
++/* ROG Ally has many settings related to the gamepad, all using the same n-key endpoint */
++struct ally_gamepad_cfg {
++ struct hid_device *hdev;
++ struct input_dev *input;
++
++ enum xpad_mode mode;
++ /*
++ * index: [mode]
++ */
++ struct btn_mapping *key_mapping[xpad_mode_mouse];
++};
++
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+ static const int hat_values[][2] = {
+ { 0, 0 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
+@@ -119,6 +171,7 @@ struct ally_rgb_data {
+ static struct ally_drvdata {
+ struct hid_device *hdev;
+ struct ally_x_device *ally_x;
++ struct ally_gamepad_cfg *gamepad_cfg;
+ struct ally_rgb_dev *led_rgb_dev;
+ struct ally_rgb_data led_rgb_data;
+ } drvdata;
+@@ -173,6 +226,172 @@ static u8 get_endpoint_address(struct hid_device *hdev)
+ return -ENODEV;
+ }
+
++/**************************************************************************************************/
++/* ROG Ally gamepad configuration */
++/**************************************************************************************************/
++
++/* This should be called before any attempts to set device functions */
++static int ally_gamepad_check_ready(struct hid_device *hdev)
++{
++ int ret, count;
++ u8 *hidbuf;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ ret = 0;
++ for (count = 0; count < READY_MAX_TRIES; count++) {
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ hidbuf[2] = xpad_cmd_check_ready;
++ hidbuf[3] = 01;
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ hid_dbg(hdev, "ROG Ally check failed set report: %d\n", ret);
++
++ hidbuf[0] = hidbuf[1] = hidbuf[2] = hidbuf[3] = 0;
++ ret = asus_dev_get_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ hid_dbg(hdev, "ROG Ally check failed get report: %d\n", ret);
++
++ ret = hidbuf[2] == xpad_cmd_check_ready;
++ if (ret)
++ break;
++ usleep_range(
++ 1000,
++ 2000); /* don't spam the entire loop in less than USB response time */
++ }
++
++ if (count == READY_MAX_TRIES)
++ hid_warn(hdev, "ROG Ally never responded with a ready\n");
++
++ kfree(hidbuf);
++ return ret;
++}
++
++/* A HID packet conatins mappings for two buttons: btn1, btn1_macro, btn2, btn2_macro */
++static void _btn_pair_to_hid_pkt(struct ally_gamepad_cfg *ally_cfg,
++ enum btn_pair_index pair,
++ struct btn_data *btn1, struct btn_data *btn2,
++ u8 *out, int out_len)
++{
++ int start = 5;
++
++ out[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ out[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ out[2] = xpad_cmd_set_mapping;
++ out[3] = pair;
++ out[4] = xpad_cmd_len_mapping;
++
++ btn_code_to_byte_array(btn1->button, &out[start]);
++ start += BTN_DATA_LEN;
++ btn_code_to_byte_array(btn1->macro, &out[start]);
++ start += BTN_DATA_LEN;
++ btn_code_to_byte_array(btn2->button, &out[start]);
++ start += BTN_DATA_LEN;
++ btn_code_to_byte_array(btn2->macro, &out[start]);
++ //print_hex_dump(KERN_DEBUG, "byte_array: ", DUMP_PREFIX_OFFSET, 64, 1, out, 64, false);
++}
++
++/* Apply the mapping pair to the device */
++static int _gamepad_apply_btn_pair(struct hid_device *hdev, struct ally_gamepad_cfg *ally_cfg,
++ enum btn_pair_index btn_pair)
++{
++ u8 mode = ally_cfg->mode - 1;
++ struct btn_data *btn1, *btn2;
++ u8 *hidbuf;
++ int ret;
++
++ ret = ally_gamepad_check_ready(hdev);
++ if (ret < 0)
++ return ret;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ switch (btn_pair) {
++ case btn_pair_m1_m2:
++ btn1 = &ally_cfg->key_mapping[mode]->btn_m1;
++ btn2 = &ally_cfg->key_mapping[mode]->btn_m2;
++ break;
++ default:
++ break;
++ }
++
++ _btn_pair_to_hid_pkt(ally_cfg, btn_pair, btn1, btn2, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++
++ kfree(hidbuf);
++
++ return ret;
++}
++
++static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
++{
++ struct ally_gamepad_cfg *ally_cfg;
++ struct input_dev *input_dev;
++ int err;
++
++ ally_cfg = devm_kzalloc(&hdev->dev, sizeof(*ally_cfg), GFP_KERNEL);
++ if (!ally_cfg)
++ return ERR_PTR(-ENOMEM);
++ ally_cfg->hdev = hdev;
++ // Allocate memory for each mode's `btn_mapping`
++ ally_cfg->mode = xpad_mode_game;
++ for (int i = 0; i < xpad_mode_mouse; i++) {
++ ally_cfg->key_mapping[i] = devm_kzalloc(&hdev->dev, sizeof(struct btn_mapping), GFP_KERNEL);
++ if (!ally_cfg->key_mapping[i]) {
++ err = -ENOMEM;
++ goto free_key_mappings;
++ }
++ }
++
++ input_dev = devm_input_allocate_device(&hdev->dev);
++ if (!input_dev) {
++ err = -ENOMEM;
++ goto free_ally_cfg;
++ }
++
++ input_dev->id.bustype = hdev->bus;
++ input_dev->id.vendor = hdev->vendor;
++ input_dev->id.product = hdev->product;
++ input_dev->id.version = hdev->version;
++ input_dev->uniq = hdev->uniq;
++ input_dev->name = "ASUS ROG Ally Config";
++ input_set_capability(input_dev, EV_KEY, KEY_PROG1);
++ input_set_capability(input_dev, EV_KEY, KEY_F16);
++ input_set_capability(input_dev, EV_KEY, KEY_F17);
++ input_set_capability(input_dev, EV_KEY, KEY_F18);
++ input_set_drvdata(input_dev, hdev);
++
++ err = input_register_device(input_dev);
++ if (err)
++ goto free_input_dev;
++ ally_cfg->input = input_dev;
++
++ /* ignore all errors for this as they are related to USB HID I/O */
++ ally_cfg->key_mapping[ally_cfg->mode - 1]->btn_m1.button = BTN_KB_M1;
++ ally_cfg->key_mapping[ally_cfg->mode - 1]->btn_m2.button = BTN_KB_M2;
++ _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_m1_m2);
++
++ return ally_cfg;
++
++free_input_dev:
++ devm_kfree(&hdev->dev, input_dev);
++
++free_key_mappings:
++ for (int i = 0; i < xpad_mode_mouse; i++) {
++ if (ally_cfg->key_mapping[i])
++ devm_kfree(&hdev->dev, ally_cfg->key_mapping[i]);
++ }
++
++free_ally_cfg:
++ devm_kfree(&hdev->dev, ally_cfg);
++ return ERR_PTR(err);
++}
++
+ /**************************************************************************************************/
+ /* ROG Ally gamepad i/o and force-feedback */
+ /**************************************************************************************************/
+@@ -729,7 +948,7 @@ static void ally_rgb_remove(struct hid_device *hdev)
+ static int ally_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data,
+ int size)
+ {
+- // struct ally_gamepad_cfg *cfg = drvdata.gamepad_cfg;
++ struct ally_gamepad_cfg *cfg = drvdata.gamepad_cfg;
+ struct ally_x_device *ally_x = drvdata.ally_x;
+
+ if (ally_x) {
+@@ -741,13 +960,13 @@ static int ally_raw_event(struct hid_device *hdev, struct hid_report *report, u8
+ return -1;
+ }
+ }
+- // if (cfg && !ally_x) {
+- // input_report_key(cfg->input, KEY_PROG1, data[1] == 0x38);
+- // input_report_key(cfg->input, KEY_F16, data[1] == 0xA6);
+- // input_report_key(cfg->input, KEY_F17, data[1] == 0xA7);
+- // input_report_key(cfg->input, KEY_F18, data[1] == 0xA8);
+- // input_sync(cfg->input);
+- // }
++ if (cfg && !ally_x) {
++ input_report_key(cfg->input, KEY_PROG1, data[1] == 0x38);
++ input_report_key(cfg->input, KEY_F16, data[1] == 0xA6);
++ input_report_key(cfg->input, KEY_F17, data[1] == 0xA7);
++ input_report_key(cfg->input, KEY_F18, data[1] == 0xA8);
++ input_sync(cfg->input);
++ }
+
+ return 0;
+ }
+@@ -866,7 +1085,7 @@ static int ally_hid_probe(struct hid_device *hdev, const struct hid_device_id *_
+ if (ep < 0)
+ return ep;
+
+- if (ep != ALLY_CFG_INTF_IN_ADDRESS ||
++ if (ep != ALLY_CFG_INTF_IN_ADDRESS &&
+ ep != ALLY_X_INTERFACE_ADDRESS)
+ return -ENODEV;
+
+@@ -906,7 +1125,13 @@ static int ally_hid_probe(struct hid_device *hdev, const struct hid_device_id *_
+ else
+ hid_info(hdev, "Created Ally RGB LED controls.\n");
+
+- if (IS_ERR(drvdata.led_rgb_dev))
++ drvdata.gamepad_cfg = ally_gamepad_cfg_create(hdev);
++ if (IS_ERR(drvdata.gamepad_cfg))
++ hid_err(hdev, "Failed to create Ally gamepad attributes.\n");
++ else
++ hid_info(hdev, "Created Ally gamepad attributes.\n");
++
++ if (IS_ERR(drvdata.led_rgb_dev) && IS_ERR(drvdata.gamepad_cfg))
+ goto err_close;
+ }
+
+@@ -921,10 +1146,10 @@ static int ally_hid_probe(struct hid_device *hdev, const struct hid_device_id *_
+ hid_info(hdev, "Created Ally X controller.\n");
+
+ // Not required since we send this inputs ep through the gamepad input dev
+- // if (drvdata.gamepad_cfg && drvdata.gamepad_cfg->input) {
+- // input_unregister_device(drvdata.gamepad_cfg->input);
+- // hid_info(hdev, "Ally X removed unrequired input dev.\n");
+- // }
++ if (drvdata.gamepad_cfg && drvdata.gamepad_cfg->input) {
++ input_unregister_device(drvdata.gamepad_cfg->input);
++ hid_info(hdev, "Ally X removed unrequired input dev.\n");
++ }
+ }
+
+ return 0;
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index 458d02996bca..2b298ad4da0e 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -8,35 +8,41 @@
+ #include
+ #include
+
++/*
++ * the xpad_mode is used inside the mode setting packet and is used
++ * for indexing (xpad_mode - 1)
++ */
++enum xpad_mode {
++ xpad_mode_game = 0x01,
++ xpad_mode_wasd = 0x02,
++ xpad_mode_mouse = 0x03,
++};
++
+ /* the xpad_cmd determines which feature is set or queried */
+ enum xpad_cmd {
+- xpad_cmd_set_mode = 0x01,
+ xpad_cmd_set_mapping = 0x02,
+- xpad_cmd_set_js_dz = 0x04, /* deadzones */
+- xpad_cmd_set_tr_dz = 0x05, /* deadzones */
+- xpad_cmd_set_vibe_intensity = 0x06,
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
+- xpad_cmd_set_calibration = 0x0D,
+- xpad_cmd_set_turbo = 0x0F,
+- xpad_cmd_set_response_curve = 0x13,
+- xpad_cmd_set_adz = 0x18,
+ };
+
+ /* the xpad_cmd determines which feature is set or queried */
+ enum xpad_cmd_len {
+- xpad_cmd_len_mode = 0x01,
+ xpad_cmd_len_mapping = 0x2c,
+- xpad_cmd_len_deadzone = 0x04,
+- xpad_cmd_len_vibe_intensity = 0x02,
+ xpad_cmd_len_leds = 0x0C,
+- xpad_cmd_len_calibration2 = 0x01,
+- xpad_cmd_len_calibration3 = 0x01,
+- xpad_cmd_len_turbo = 0x20,
+- xpad_cmd_len_response_curve = 0x09,
+- xpad_cmd_len_adz = 0x02,
+ };
+
++/* Values correspond to the actual HID byte value required */
++enum btn_pair_index {
++ btn_pair_m1_m2 = 0x08,
++};
++
++#define BTN_KB_M2 0x02008E0000000000
++#define BTN_KB_M1 0x02008F0000000000
++
++#define ALLY_DEVICE_ATTR_WO(_name, _sysfs_name) \
++ struct device_attribute dev_attr_##_name = \
++ __ATTR(_sysfs_name, 0200, NULL, _name##_store)
++
+ /* required so we can have nested attributes with same name but different functions */
+ #define ALLY_DEVICE_ATTR_RW(_name, _sysfs_name) \
+ struct device_attribute dev_attr_##_name = \
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0017-ACPI-PM-Quirk-ASUS-ROG-M16-to-default-to-S3-sleep.patch b/packages/l/linux-current/files/patches/hardware/asus/0017-ACPI-PM-Quirk-ASUS-ROG-M16-to-default-to-S3-sleep.patch
deleted file mode 100644
index 978a289eae9..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0017-ACPI-PM-Quirk-ASUS-ROG-M16-to-default-to-S3-sleep.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones"
-Date: Sun, 8 Sep 2024 17:30:43 +1200
-Subject: [PATCH 17/18] ACPI: PM: Quirk ASUS ROG M16 to default to S3 sleep
-
-The 2023 ASUS ROG Zephyrus M16 can suffer from quite a variety of events
-causing wakeup from s2idle sleep. The events may come from the EC being
-noisey, from the MMC reader, from the AniMe matrix display on some models
-or from AC events.
-
-Defaulting to S3 sleep prevents all these wakeup issues.
-
-Signed-off-by: Luke D. Jones
----
- drivers/acpi/sleep.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
-diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
-index 889f1c1a1fa9..c8ee8e42b0f6 100644
---- a/drivers/acpi/sleep.c
-+++ b/drivers/acpi/sleep.c
-@@ -351,6 +351,20 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
- DMI_MATCH(DMI_PRODUCT_NAME, "1025C"),
- },
- },
-+ /*
-+ * The ASUS ROG M16 from 2023 has many events which wake it from s2idle
-+ * resulting in excessive battery drain and risk of laptop overheating,
-+ * these events can be caused by the MMC or y AniMe display if installed.
-+ * The match is valid for all of the GU604V range.
-+ */
-+ {
-+ .callback = init_default_s3,
-+ .ident = "ASUS ROG Zephyrus M16 (2023)",
-+ .matches = {
-+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-+ DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus M16 GU604V"),
-+ },
-+ },
- /*
- * https://bugzilla.kernel.org/show_bug.cgi?id=189431
- * Lenovo G50-45 is a platform later than 2012, but needs nvs memory
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0017-hid-asus-ally-add-button-remap-attributes.patch b/packages/l/linux-current/files/patches/hardware/asus/0017-hid-asus-ally-add-button-remap-attributes.patch
new file mode 100644
index 00000000000..f5dd0392eb9
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0017-hid-asus-ally-add-button-remap-attributes.patch
@@ -0,0 +1,694 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sat, 5 Oct 2024 14:58:33 +1300
+Subject: [PATCH 17/27] hid-asus-ally: add button remap attributes
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 393 ++++++++++++++++++++++++++++++++++--
+ drivers/hid/hid-asus-ally.h | 197 ++++++++++++++++++
+ 2 files changed, 572 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index eed1bc84026d..56cc7abc397f 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -54,6 +54,152 @@ struct btn_code_map {
+ const char *name;
+ };
+
++static const struct btn_code_map ally_btn_codes[] = {
++ { 0, "NONE" },
++ /* Gamepad button codes */
++ { BTN_PAD_A, "PAD_A" },
++ { BTN_PAD_B, "PAD_B" },
++ { BTN_PAD_X, "PAD_X" },
++ { BTN_PAD_Y, "PAD_Y" },
++ { BTN_PAD_LB, "PAD_LB" },
++ { BTN_PAD_RB, "PAD_RB" },
++ { BTN_PAD_LS, "PAD_LS" },
++ { BTN_PAD_RS, "PAD_RS" },
++ { BTN_PAD_DPAD_UP, "PAD_DPAD_UP" },
++ { BTN_PAD_DPAD_DOWN, "PAD_DPAD_DOWN" },
++ { BTN_PAD_DPAD_LEFT, "PAD_DPAD_LEFT" },
++ { BTN_PAD_DPAD_RIGHT, "PAD_DPAD_RIGHT" },
++ { BTN_PAD_VIEW, "PAD_VIEW" },
++ { BTN_PAD_MENU, "PAD_MENU" },
++ { BTN_PAD_XBOX, "PAD_XBOX" },
++
++ /* Triggers mapped to keyboard codes */
++ { BTN_KB_M2, "KB_M2" },
++ { BTN_KB_M1, "KB_M1" },
++ { BTN_KB_ESC, "KB_ESC" },
++ { BTN_KB_F1, "KB_F1" },
++ { BTN_KB_F2, "KB_F2" },
++ { BTN_KB_F3, "KB_F3" },
++ { BTN_KB_F4, "KB_F4" },
++ { BTN_KB_F5, "KB_F5" },
++ { BTN_KB_F6, "KB_F6" },
++ { BTN_KB_F7, "KB_F7" },
++ { BTN_KB_F8, "KB_F8" },
++ { BTN_KB_F9, "KB_F9" },
++ { BTN_KB_F10, "KB_F10" },
++ { BTN_KB_F11, "KB_F11" },
++ { BTN_KB_F12, "KB_F12" },
++ { BTN_KB_F14, "KB_F14" },
++ { BTN_KB_F15, "KB_F15" },
++ { BTN_KB_BACKTICK, "KB_BACKTICK" },
++ { BTN_KB_1, "KB_1" },
++ { BTN_KB_2, "KB_2" },
++ { BTN_KB_3, "KB_3" },
++ { BTN_KB_4, "KB_4" },
++ { BTN_KB_5, "KB_5" },
++ { BTN_KB_6, "KB_6" },
++ { BTN_KB_7, "KB_7" },
++ { BTN_KB_8, "KB_8" },
++ { BTN_KB_9, "KB_9" },
++ { BTN_KB_0, "KB_0" },
++ { BTN_KB_HYPHEN, "KB_HYPHEN" },
++ { BTN_KB_EQUALS, "KB_EQUALS" },
++ { BTN_KB_BACKSPACE, "KB_BACKSPACE" },
++ { BTN_KB_TAB, "KB_TAB" },
++ { BTN_KB_Q, "KB_Q" },
++ { BTN_KB_W, "KB_W" },
++ { BTN_KB_E, "KB_E" },
++ { BTN_KB_R, "KB_R" },
++ { BTN_KB_T, "KB_T" },
++ { BTN_KB_Y, "KB_Y" },
++ { BTN_KB_U, "KB_U" },
++ { BTN_KB_O, "KB_O" },
++ { BTN_KB_P, "KB_P" },
++ { BTN_KB_LBRACKET, "KB_LBRACKET" },
++ { BTN_KB_RBRACKET, "KB_RBRACKET" },
++ { BTN_KB_BACKSLASH, "KB_BACKSLASH" },
++ { BTN_KB_CAPS, "KB_CAPS" },
++ { BTN_KB_A, "KB_A" },
++ { BTN_KB_S, "KB_S" },
++ { BTN_KB_D, "KB_D" },
++ { BTN_KB_F, "KB_F" },
++ { BTN_KB_G, "KB_G" },
++ { BTN_KB_H, "KB_H" },
++ { BTN_KB_J, "KB_J" },
++ { BTN_KB_K, "KB_K" },
++ { BTN_KB_L, "KB_L" },
++ { BTN_KB_SEMI, "KB_SEMI" },
++ { BTN_KB_QUOTE, "KB_QUOTE" },
++ { BTN_KB_RET, "KB_RET" },
++ { BTN_KB_LSHIFT, "KB_LSHIFT" },
++ { BTN_KB_Z, "KB_Z" },
++ { BTN_KB_X, "KB_X" },
++ { BTN_KB_C, "KB_C" },
++ { BTN_KB_V, "KB_V" },
++ { BTN_KB_B, "KB_B" },
++ { BTN_KB_N, "KB_N" },
++ { BTN_KB_M, "KB_M" },
++ { BTN_KB_COMMA, "KB_COMMA" },
++ { BTN_KB_PERIOD, "KB_PERIOD" },
++ { BTN_KB_RSHIFT, "KB_RSHIFT" },
++ { BTN_KB_LCTL, "KB_LCTL" },
++ { BTN_KB_META, "KB_META" },
++ { BTN_KB_LALT, "KB_LALT" },
++ { BTN_KB_SPACE, "KB_SPACE" },
++ { BTN_KB_RALT, "KB_RALT" },
++ { BTN_KB_MENU, "KB_MENU" },
++ { BTN_KB_RCTL, "KB_RCTL" },
++ { BTN_KB_PRNTSCN, "KB_PRNTSCN" },
++ { BTN_KB_SCRLCK, "KB_SCRLCK" },
++ { BTN_KB_PAUSE, "KB_PAUSE" },
++ { BTN_KB_INS, "KB_INS" },
++ { BTN_KB_HOME, "KB_HOME" },
++ { BTN_KB_PGUP, "KB_PGUP" },
++ { BTN_KB_DEL, "KB_DEL" },
++ { BTN_KB_END, "KB_END" },
++ { BTN_KB_PGDWN, "KB_PGDWN" },
++ { BTN_KB_UP_ARROW, "KB_UP_ARROW" },
++ { BTN_KB_DOWN_ARROW, "KB_DOWN_ARROW" },
++ { BTN_KB_LEFT_ARROW, "KB_LEFT_ARROW" },
++ { BTN_KB_RIGHT_ARROW, "KB_RIGHT_ARROW" },
++
++ /* Numpad mappings */
++ { BTN_NUMPAD_LOCK, "NUMPAD_LOCK" },
++ { BTN_NUMPAD_FWDSLASH, "NUMPAD_FWDSLASH" },
++ { BTN_NUMPAD_ASTERISK, "NUMPAD_ASTERISK" },
++ { BTN_NUMPAD_HYPHEN, "NUMPAD_HYPHEN" },
++ { BTN_NUMPAD_0, "NUMPAD_0" },
++ { BTN_NUMPAD_1, "NUMPAD_1" },
++ { BTN_NUMPAD_2, "NUMPAD_2" },
++ { BTN_NUMPAD_3, "NUMPAD_3" },
++ { BTN_NUMPAD_4, "NUMPAD_4" },
++ { BTN_NUMPAD_5, "NUMPAD_5" },
++ { BTN_NUMPAD_6, "NUMPAD_6" },
++ { BTN_NUMPAD_7, "NUMPAD_7" },
++ { BTN_NUMPAD_8, "NUMPAD_8" },
++ { BTN_NUMPAD_9, "NUMPAD_9" },
++ { BTN_NUMPAD_PLUS, "NUMPAD_PLUS" },
++ { BTN_NUMPAD_ENTER, "NUMPAD_ENTER" },
++ { BTN_NUMPAD_PERIOD, "NUMPAD_PERIOD" },
++
++ /* Mouse mappings */
++ { BTN_MOUSE_LCLICK, "MOUSE_LCLICK" },
++ { BTN_MOUSE_RCLICK, "MOUSE_RCLICK" },
++ { BTN_MOUSE_MCLICK, "MOUSE_MCLICK" },
++ { BTN_MOUSE_WHEEL_UP, "MOUSE_WHEEL_UP" },
++ { BTN_MOUSE_WHEEL_DOWN, "MOUSE_WHEEL_DOWN" },
++
++ /* Media mappings */
++ { BTN_MEDIA_SCREENSHOT, "MEDIA_SCREENSHOT" },
++ { BTN_MEDIA_SHOW_KEYBOARD, "MEDIA_SHOW_KEYBOARD" },
++ { BTN_MEDIA_SHOW_DESKTOP, "MEDIA_SHOW_DESKTOP" },
++ { BTN_MEDIA_START_RECORDING, "MEDIA_START_RECORDING" },
++ { BTN_MEDIA_MIC_OFF, "MEDIA_MIC_OFF" },
++ { BTN_MEDIA_VOL_DOWN, "MEDIA_VOL_DOWN" },
++ { BTN_MEDIA_VOL_UP, "MEDIA_VOL_UP" },
++};
++static const size_t keymap_len = ARRAY_SIZE(ally_btn_codes);
++
+ /* byte_array must be >= 8 in length */
+ static void btn_code_to_byte_array(u64 keycode, u8 *byte_array)
+ {
+@@ -63,6 +209,27 @@ static void btn_code_to_byte_array(u64 keycode, u8 *byte_array)
+ }
+ }
+
++static u64 name_to_btn(const char *name)
++{
++ int len = strcspn(name, "\n");
++ for (size_t i = 0; i < keymap_len; ++i) {
++ if (strncmp(ally_btn_codes[i].name, name, len) == 0) {
++ return ally_btn_codes[i].code;
++ }
++ }
++ return -EINVAL;
++}
++
++static const char* btn_to_name(u64 key)
++{
++ for (size_t i = 0; i < keymap_len; ++i) {
++ if (ally_btn_codes[i].code == key) {
++ return ally_btn_codes[i].name;
++ }
++ }
++ return NULL;
++}
++
+ struct btn_data {
+ u64 button;
+ u64 macro;
+@@ -98,7 +265,7 @@ struct ally_gamepad_cfg {
+ /*
+ * index: [mode]
+ */
+- struct btn_mapping *key_mapping[xpad_mode_mouse];
++ struct btn_mapping key_mapping[xpad_mode_mouse];
+ };
+
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+@@ -312,9 +479,41 @@ static int _gamepad_apply_btn_pair(struct hid_device *hdev, struct ally_gamepad_
+ return -ENOMEM;
+
+ switch (btn_pair) {
++ case btn_pair_dpad_u_d:
++ btn1 = &ally_cfg->key_mapping[mode].dpad_up;
++ btn2 = &ally_cfg->key_mapping[mode].dpad_down;
++ break;
++ case btn_pair_dpad_l_r:
++ btn1 = &ally_cfg->key_mapping[mode].dpad_left;
++ btn2 = &ally_cfg->key_mapping[mode].dpad_right;
++ break;
++ case btn_pair_ls_rs:
++ btn1 = &ally_cfg->key_mapping[mode].btn_ls;
++ btn2 = &ally_cfg->key_mapping[mode].btn_rs;
++ break;
++ case btn_pair_lb_rb:
++ btn1 = &ally_cfg->key_mapping[mode].btn_lb;
++ btn2 = &ally_cfg->key_mapping[mode].btn_rb;
++ break;
++ case btn_pair_lt_rt:
++ btn1 = &ally_cfg->key_mapping[mode].btn_lt;
++ btn2 = &ally_cfg->key_mapping[mode].btn_rt;
++ break;
++ case btn_pair_a_b:
++ btn1 = &ally_cfg->key_mapping[mode].btn_a;
++ btn2 = &ally_cfg->key_mapping[mode].btn_b;
++ break;
++ case btn_pair_x_y:
++ btn1 = &ally_cfg->key_mapping[mode].btn_x;
++ btn2 = &ally_cfg->key_mapping[mode].btn_y;
++ break;
++ case btn_pair_view_menu:
++ btn1 = &ally_cfg->key_mapping[mode].btn_view;
++ btn2 = &ally_cfg->key_mapping[mode].btn_menu;
++ break;
+ case btn_pair_m1_m2:
+- btn1 = &ally_cfg->key_mapping[mode]->btn_m1;
+- btn2 = &ally_cfg->key_mapping[mode]->btn_m2;
++ btn1 = &ally_cfg->key_mapping[mode].btn_m1;
++ btn2 = &ally_cfg->key_mapping[mode].btn_m2;
+ break;
+ default:
+ break;
+@@ -328,6 +527,157 @@ static int _gamepad_apply_btn_pair(struct hid_device *hdev, struct ally_gamepad_
+ return ret;
+ }
+
++static ssize_t _gamepad_apply_all(struct hid_device *hdev, struct ally_gamepad_cfg *ally_cfg)
++{
++ int ret;
++
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_dpad_u_d);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_dpad_l_r);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_ls_rs);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_lb_rb);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_a_b);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_x_y);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_view_menu);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_m1_m2);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_lt_rt);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static ssize_t gamepad_apply_all_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++ struct hid_device *hdev = to_hid_device(dev);
++ int ret;
++
++ if (!drvdata.gamepad_cfg)
++ return -ENODEV;
++
++ ret = _gamepad_apply_all(hdev, ally_cfg);
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++ALLY_DEVICE_ATTR_WO(gamepad_apply_all, apply_all);
++
++/* button map attributes, regular and macro*/
++ALLY_BTN_MAPPING(m1, btn_m1);
++ALLY_BTN_MAPPING(m2, btn_m2);
++ALLY_BTN_MAPPING(a, btn_a);
++ALLY_BTN_MAPPING(b, btn_b);
++ALLY_BTN_MAPPING(x, btn_x);
++ALLY_BTN_MAPPING(y, btn_y);
++ALLY_BTN_MAPPING(lb, btn_lb);
++ALLY_BTN_MAPPING(rb, btn_rb);
++ALLY_BTN_MAPPING(ls, btn_ls);
++ALLY_BTN_MAPPING(rs, btn_rs);
++ALLY_BTN_MAPPING(lt, btn_lt);
++ALLY_BTN_MAPPING(rt, btn_rt);
++ALLY_BTN_MAPPING(dpad_u, dpad_up);
++ALLY_BTN_MAPPING(dpad_d, dpad_down);
++ALLY_BTN_MAPPING(dpad_l, dpad_left);
++ALLY_BTN_MAPPING(dpad_r, dpad_right);
++ALLY_BTN_MAPPING(view, btn_view);
++ALLY_BTN_MAPPING(menu, btn_menu);
++
++static void _gamepad_set_xpad_default(struct ally_gamepad_cfg *ally_cfg)
++{
++ struct btn_mapping *map = &ally_cfg->key_mapping[ally_cfg->mode - 1];
++ map->btn_m1.button = BTN_KB_M1;
++ map->btn_m2.button = BTN_KB_M2;
++ map->btn_a.button = BTN_PAD_A;
++ map->btn_b.button = BTN_PAD_B;
++ map->btn_x.button = BTN_PAD_X;
++ map->btn_y.button = BTN_PAD_Y;
++ map->btn_lb.button = BTN_PAD_LB;
++ map->btn_rb.button = BTN_PAD_RB;
++ map->btn_lt.button = BTN_PAD_LT;
++ map->btn_rt.button = BTN_PAD_RT;
++ map->btn_ls.button = BTN_PAD_LS;
++ map->btn_rs.button = BTN_PAD_RS;
++ map->dpad_up.button = BTN_PAD_DPAD_UP;
++ map->dpad_down.button = BTN_PAD_DPAD_DOWN;
++ map->dpad_left.button = BTN_PAD_DPAD_LEFT;
++ map->dpad_right.button = BTN_PAD_DPAD_RIGHT;
++ map->btn_view.button = BTN_PAD_VIEW;
++ map->btn_menu.button = BTN_PAD_MENU;
++}
++
++static ssize_t btn_mapping_reset_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++
++ if (!drvdata.gamepad_cfg)
++ return -ENODEV;
++
++ switch (ally_cfg->mode) {
++ case xpad_mode_game:
++ _gamepad_set_xpad_default(ally_cfg);
++ break;
++ default:
++ _gamepad_set_xpad_default(ally_cfg);
++ break;
++ }
++
++ return count;
++}
++ALLY_DEVICE_ATTR_WO(btn_mapping_reset, reset_btn_mapping);
++
++/* ROOT LEVEL ATTRS *******************************************************************************/
++static struct attribute *gamepad_device_attrs[] = {
++ &dev_attr_btn_mapping_reset.attr,
++ &dev_attr_gamepad_apply_all.attr,
++ NULL
++};
++
++static const struct attribute_group ally_controller_attr_group = {
++ .attrs = gamepad_device_attrs,
++};
++
++static const struct attribute_group *gamepad_device_attr_groups[] = {
++ &ally_controller_attr_group,
++ &btn_mapping_m1_attr_group,
++ &btn_mapping_m2_attr_group,
++ &btn_mapping_a_attr_group,
++ &btn_mapping_b_attr_group,
++ &btn_mapping_x_attr_group,
++ &btn_mapping_y_attr_group,
++ &btn_mapping_lb_attr_group,
++ &btn_mapping_rb_attr_group,
++ &btn_mapping_ls_attr_group,
++ &btn_mapping_rs_attr_group,
++ &btn_mapping_lt_attr_group,
++ &btn_mapping_rt_attr_group,
++ &btn_mapping_dpad_u_attr_group,
++ &btn_mapping_dpad_d_attr_group,
++ &btn_mapping_dpad_l_attr_group,
++ &btn_mapping_dpad_r_attr_group,
++ &btn_mapping_view_attr_group,
++ &btn_mapping_menu_attr_group,
++ NULL,
++};
++
+ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+ {
+ struct ally_gamepad_cfg *ally_cfg;
+@@ -340,13 +690,6 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+ ally_cfg->hdev = hdev;
+ // Allocate memory for each mode's `btn_mapping`
+ ally_cfg->mode = xpad_mode_game;
+- for (int i = 0; i < xpad_mode_mouse; i++) {
+- ally_cfg->key_mapping[i] = devm_kzalloc(&hdev->dev, sizeof(struct btn_mapping), GFP_KERNEL);
+- if (!ally_cfg->key_mapping[i]) {
+- err = -ENOMEM;
+- goto free_key_mappings;
+- }
+- }
+
+ input_dev = devm_input_allocate_device(&hdev->dev);
+ if (!input_dev) {
+@@ -372,26 +715,37 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+ ally_cfg->input = input_dev;
+
+ /* ignore all errors for this as they are related to USB HID I/O */
+- ally_cfg->key_mapping[ally_cfg->mode - 1]->btn_m1.button = BTN_KB_M1;
+- ally_cfg->key_mapping[ally_cfg->mode - 1]->btn_m2.button = BTN_KB_M2;
++ _gamepad_set_xpad_default(ally_cfg);
++ ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m1.button = BTN_KB_M1;
++ ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m2.button = BTN_KB_M2;
+ _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_m1_m2);
+
++ drvdata.gamepad_cfg = ally_cfg; // Must asign before attr group setup
++ if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {
++ err = -ENODEV;
++ goto unregister_input_dev;
++ }
++
+ return ally_cfg;
+
++unregister_input_dev:
++ input_unregister_device(input_dev);
++ ally_cfg->input = NULL; // Prevent double free when kfree(ally_cfg) happens
++
+ free_input_dev:
+ devm_kfree(&hdev->dev, input_dev);
+
+-free_key_mappings:
+- for (int i = 0; i < xpad_mode_mouse; i++) {
+- if (ally_cfg->key_mapping[i])
+- devm_kfree(&hdev->dev, ally_cfg->key_mapping[i]);
+- }
+-
+ free_ally_cfg:
+ devm_kfree(&hdev->dev, ally_cfg);
+ return ERR_PTR(err);
+ }
+
++static void ally_cfg_remove(struct hid_device *hdev)
++{
++ // __gamepad_set_mode(hdev, drvdata.gamepad_cfg, xpad_mode_mouse);
++ sysfs_remove_groups(&hdev->dev.kobj, gamepad_device_attr_groups);
++}
++
+ /**************************************************************************************************/
+ /* ROG Ally gamepad i/o and force-feedback */
+ /**************************************************************************************************/
+@@ -1169,6 +1523,9 @@ static void ally_hid_remove(struct hid_device *hdev)
+ if (drvdata.ally_x)
+ ally_x_remove(hdev);
+
++ if (drvdata.gamepad_cfg)
++ ally_cfg_remove(hdev);
++
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+ }
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index 2b298ad4da0e..127db570a827 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -33,11 +33,155 @@ enum xpad_cmd_len {
+
+ /* Values correspond to the actual HID byte value required */
+ enum btn_pair_index {
++ btn_pair_dpad_u_d = 0x01,
++ btn_pair_dpad_l_r = 0x02,
++ btn_pair_ls_rs = 0x03,
++ btn_pair_lb_rb = 0x04,
++ btn_pair_a_b = 0x05,
++ btn_pair_x_y = 0x06,
++ btn_pair_view_menu = 0x07,
+ btn_pair_m1_m2 = 0x08,
++ btn_pair_lt_rt = 0x09,
+ };
+
++#define BTN_PAD_A 0x0101000000000000
++#define BTN_PAD_B 0x0102000000000000
++#define BTN_PAD_X 0x0103000000000000
++#define BTN_PAD_Y 0x0104000000000000
++#define BTN_PAD_LB 0x0105000000000000
++#define BTN_PAD_RB 0x0106000000000000
++#define BTN_PAD_LS 0x0107000000000000
++#define BTN_PAD_RS 0x0108000000000000
++#define BTN_PAD_DPAD_UP 0x0109000000000000
++#define BTN_PAD_DPAD_DOWN 0x010A000000000000
++#define BTN_PAD_DPAD_LEFT 0x010B000000000000
++#define BTN_PAD_DPAD_RIGHT 0x010C000000000000
++#define BTN_PAD_LT 0x010D000000000000
++#define BTN_PAD_RT 0x010E000000000000
++#define BTN_PAD_VIEW 0x0111000000000000
++#define BTN_PAD_MENU 0x0112000000000000
++#define BTN_PAD_XBOX 0x0113000000000000
++
+ #define BTN_KB_M2 0x02008E0000000000
+ #define BTN_KB_M1 0x02008F0000000000
++#define BTN_KB_ESC 0x0200760000000000
++#define BTN_KB_F1 0x0200500000000000
++#define BTN_KB_F2 0x0200600000000000
++#define BTN_KB_F3 0x0200400000000000
++#define BTN_KB_F4 0x02000C0000000000
++#define BTN_KB_F5 0x0200030000000000
++#define BTN_KB_F6 0x02000B0000000000
++#define BTN_KB_F7 0x0200800000000000
++#define BTN_KB_F8 0x02000A0000000000
++#define BTN_KB_F9 0x0200010000000000
++#define BTN_KB_F10 0x0200090000000000
++#define BTN_KB_F11 0x0200780000000000
++#define BTN_KB_F12 0x0200070000000000
++#define BTN_KB_F14 0x0200180000000000
++#define BTN_KB_F15 0x0200100000000000
++#define BTN_KB_BACKTICK 0x02000E0000000000
++#define BTN_KB_1 0x0200160000000000
++#define BTN_KB_2 0x02001E0000000000
++#define BTN_KB_3 0x0200260000000000
++#define BTN_KB_4 0x0200250000000000
++#define BTN_KB_5 0x02002E0000000000
++#define BTN_KB_6 0x0200360000000000
++#define BTN_KB_7 0x02003D0000000000
++#define BTN_KB_8 0x02003E0000000000
++#define BTN_KB_9 0x0200460000000000
++#define BTN_KB_0 0x0200450000000000
++#define BTN_KB_HYPHEN 0x02004E0000000000
++#define BTN_KB_EQUALS 0x0200550000000000
++#define BTN_KB_BACKSPACE 0x0200660000000000
++#define BTN_KB_TAB 0x02000D0000000000
++#define BTN_KB_Q 0x0200150000000000
++#define BTN_KB_W 0x02001D0000000000
++#define BTN_KB_E 0x0200240000000000
++#define BTN_KB_R 0x02002D0000000000
++#define BTN_KB_T 0x02002C0000000000
++#define BTN_KB_Y 0x0200350000000000
++#define BTN_KB_U 0x02003C0000000000
++#define BTN_KB_O 0x0200440000000000
++#define BTN_KB_P 0x02004D0000000000
++#define BTN_KB_LBRACKET 0x0200540000000000
++#define BTN_KB_RBRACKET 0x02005B0000000000
++#define BTN_KB_BACKSLASH 0x02005D0000000000
++#define BTN_KB_CAPS 0x0200580000000000
++#define BTN_KB_A 0x02001C0000000000
++#define BTN_KB_S 0x02001B0000000000
++#define BTN_KB_D 0x0200230000000000
++#define BTN_KB_F 0x02002B0000000000
++#define BTN_KB_G 0x0200340000000000
++#define BTN_KB_H 0x0200330000000000
++#define BTN_KB_J 0x02003B0000000000
++#define BTN_KB_K 0x0200420000000000
++#define BTN_KB_L 0x02004B0000000000
++#define BTN_KB_SEMI 0x02004C0000000000
++#define BTN_KB_QUOTE 0x0200520000000000
++#define BTN_KB_RET 0x02005A0000000000
++#define BTN_KB_LSHIFT 0x0200880000000000
++#define BTN_KB_Z 0x02001A0000000000
++#define BTN_KB_X 0x0200220000000000
++#define BTN_KB_C 0x0200210000000000
++#define BTN_KB_V 0x02002A0000000000
++#define BTN_KB_B 0x0200320000000000
++#define BTN_KB_N 0x0200310000000000
++#define BTN_KB_M 0x02003A0000000000
++#define BTN_KB_COMMA 0x0200410000000000
++#define BTN_KB_PERIOD 0x0200490000000000
++#define BTN_KB_RSHIFT 0x0200890000000000
++#define BTN_KB_LCTL 0x02008C0000000000
++#define BTN_KB_META 0x0200820000000000
++#define BTN_KB_LALT 0x02008A0000000000
++#define BTN_KB_SPACE 0x0200290000000000
++#define BTN_KB_RALT 0x02008B0000000000
++#define BTN_KB_MENU 0x0200840000000000
++#define BTN_KB_RCTL 0x02008D0000000000
++#define BTN_KB_PRNTSCN 0x0200C30000000000
++#define BTN_KB_SCRLCK 0x02007E0000000000
++#define BTN_KB_PAUSE 0x0200910000000000
++#define BTN_KB_INS 0x0200C20000000000
++#define BTN_KB_HOME 0x0200940000000000
++#define BTN_KB_PGUP 0x0200960000000000
++#define BTN_KB_DEL 0x0200C00000000000
++#define BTN_KB_END 0x0200950000000000
++#define BTN_KB_PGDWN 0x0200970000000000
++#define BTN_KB_UP_ARROW 0x0200980000000000
++#define BTN_KB_DOWN_ARROW 0x0200990000000000
++#define BTN_KB_LEFT_ARROW 0x0200910000000000
++#define BTN_KB_RIGHT_ARROW 0x02009B0000000000
++
++#define BTN_NUMPAD_LOCK 0x0200770000000000
++#define BTN_NUMPAD_FWDSLASH 0x0200900000000000
++#define BTN_NUMPAD_ASTERISK 0x02007C0000000000
++#define BTN_NUMPAD_HYPHEN 0x02007B0000000000
++#define BTN_NUMPAD_0 0x0200700000000000
++#define BTN_NUMPAD_1 0x0200690000000000
++#define BTN_NUMPAD_2 0x0200720000000000
++#define BTN_NUMPAD_3 0x02007A0000000000
++#define BTN_NUMPAD_4 0x02006B0000000000
++#define BTN_NUMPAD_5 0x0200730000000000
++#define BTN_NUMPAD_6 0x0200740000000000
++#define BTN_NUMPAD_7 0x02006C0000000000
++#define BTN_NUMPAD_8 0x0200750000000000
++#define BTN_NUMPAD_9 0x02007D0000000000
++#define BTN_NUMPAD_PLUS 0x0200790000000000
++#define BTN_NUMPAD_ENTER 0x0200810000000000
++#define BTN_NUMPAD_PERIOD 0x0200710000000000
++
++#define BTN_MOUSE_LCLICK 0x0300000001000000
++#define BTN_MOUSE_RCLICK 0x0300000002000000
++#define BTN_MOUSE_MCLICK 0x0300000003000000
++#define BTN_MOUSE_WHEEL_UP 0x0300000004000000
++#define BTN_MOUSE_WHEEL_DOWN 0x0300000005000000
++
++#define BTN_MEDIA_SCREENSHOT 0x0500001600000000
++#define BTN_MEDIA_SHOW_KEYBOARD 0x0500001900000000
++#define BTN_MEDIA_SHOW_DESKTOP 0x0500001C00000000
++#define BTN_MEDIA_START_RECORDING 0x0500001E00000000
++#define BTN_MEDIA_MIC_OFF 0x0500000100000000
++#define BTN_MEDIA_VOL_DOWN 0x0500000200000000
++#define BTN_MEDIA_VOL_UP 0x0500000300000000
+
+ #define ALLY_DEVICE_ATTR_WO(_name, _sysfs_name) \
+ struct device_attribute dev_attr_##_name = \
+@@ -47,3 +191,56 @@ enum btn_pair_index {
+ #define ALLY_DEVICE_ATTR_RW(_name, _sysfs_name) \
+ struct device_attribute dev_attr_##_name = \
+ __ATTR(_sysfs_name, 0644, _name##_show, _name##_store)
++
++/* button specific macros */
++#define ALLY_BTN_SHOW(_fname, _btn_name, _secondary) \
++ static ssize_t _fname##_show(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ struct btn_data *btn; \
++ const char* name; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ btn = &ally_cfg->key_mapping[ally_cfg->mode - 1]._btn_name; \
++ name = btn_to_name(_secondary ? btn->macro : btn->button); \
++ return sysfs_emit(buf, "%s\n", name); \
++ }
++
++#define ALLY_BTN_STORE(_fname, _btn_name, _secondary) \
++ static ssize_t _fname##_store(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ struct btn_data *btn; \
++ u64 code; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ btn = &ally_cfg->key_mapping[ally_cfg->mode - 1]._btn_name; \
++ code = name_to_btn(buf); \
++ if (_secondary) \
++ btn->macro = code; \
++ else \
++ btn->button = code; \
++ return count; \
++ }
++
++#define ALLY_BTN_ATTRS_GROUP(_name, _fname) \
++ static struct attribute *_fname##_attrs[] = { \
++ &dev_attr_##_fname.attr, \
++ &dev_attr_##_fname##_macro.attr, \
++ }; \
++ static const struct attribute_group _fname##_attr_group = { \
++ .name = __stringify(_name), \
++ .attrs = _fname##_attrs, \
++ }
++
++#define ALLY_BTN_MAPPING(_fname, _mname) \
++ ALLY_BTN_SHOW(btn_mapping_##_fname, _mname, false); \
++ ALLY_BTN_STORE(btn_mapping_##_fname, _mname, false); \
++ ALLY_BTN_SHOW(btn_mapping_##_fname##_macro, _mname, true); \
++ ALLY_BTN_STORE(btn_mapping_##_fname##_macro, _mname, true); \
++ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname, remap); \
++ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname##_macro, macro_remap); \
++ ALLY_BTN_ATTRS_GROUP(btn_##_fname, btn_mapping_##_fname)
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0018-Bluetooth-btusb-Add-2-USB-HW-IDs-for-MT7925-0xe118-e.patch b/packages/l/linux-current/files/patches/hardware/asus/0018-Bluetooth-btusb-Add-2-USB-HW-IDs-for-MT7925-0xe118-e.patch
deleted file mode 100644
index 9cbbae3dc97..00000000000
--- a/packages/l/linux-current/files/patches/hardware/asus/0018-Bluetooth-btusb-Add-2-USB-HW-IDs-for-MT7925-0xe118-e.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Michael Burch
-Date: Sun, 1 Sep 2024 04:28:47 +0000
-Subject: [PATCH 18/18] Bluetooth: btusb: Add 2 USB HW IDs for MT7925
- (0xe118/e)
-
-Add 2 USB HW IDs for MT7925 (0xe118/e) to ensure proper recognition.
-
-These HW IDs are extracted from Windows driver inf file:
-https://dlcdnets.asus.com/pub/ASUS/nb/Image/Driver/Bluetooth/39389/Bluetooth_DCH_MediaTek_B_V1.1037.0.433Sub2_39389.exe?model=H7606WV
-
-Patch has been tested successfully on an Asus ProArt P16 model H7606WV.
-Controller is recognized devices pair successfully.
-
-Signed-off-by: Michael Burch
-Signed-off-by: Luiz Augusto von Dentz
----
- drivers/bluetooth/btusb.c | 6 ++++++
- drivers/pci/vgaarb.c | 23 ++++++++++++++++-------
- sound/pci/hda/patch_realtek.c | 2 +-
- 3 files changed, 23 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
-index 93dbeb8b348d..800cec64c9d9 100644
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -692,6 +692,12 @@ static const struct usb_device_id quirks_table[] = {
- { USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK |
- BTUSB_WIDEBAND_SPEECH |
- BTUSB_VALID_LE_STATES },
-+ { USB_DEVICE(0x0489, 0xe118), .driver_info = BTUSB_MEDIATEK |
-+ BTUSB_WIDEBAND_SPEECH |
-+ BTUSB_VALID_LE_STATES },
-+ { USB_DEVICE(0x0489, 0xe11e), .driver_info = BTUSB_MEDIATEK |
-+ BTUSB_WIDEBAND_SPEECH |
-+ BTUSB_VALID_LE_STATES },
- { USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK |
- BTUSB_WIDEBAND_SPEECH |
- BTUSB_VALID_LE_STATES },
-diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
-index 78748e8d2dba..6acb23f48468 100644
---- a/drivers/pci/vgaarb.c
-+++ b/drivers/pci/vgaarb.c
-@@ -620,9 +620,11 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
- * We always prefer a firmware default device, so if we've already
- * found one, there's no need to consider vgadev.
- */
-- if (boot_vga && boot_vga->is_firmware_default)
-- return false;
-+ if (boot_vga && boot_vga->is_firmware_default){
-+ pr_info("boot_vga->is_firmware_default: %d", boot_vga->is_firmware_default);
-+ return false;}
-
-+ pr_info("vga_is_firmware_default(pdev): %d", vga_is_firmware_default(pdev));
- if (vga_is_firmware_default(pdev)) {
- vgadev->is_firmware_default = true;
- return true;
-@@ -638,11 +640,14 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
- * vgadev is no better.
- */
- if (boot_vga &&
-- (boot_vga->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
-- return false;
-+ (boot_vga->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK){
-+ pr_info("(boot_vga->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK): %d", (boot_vga->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK);
-+ return false;}
-
-- if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
-+ if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK){
-+ pr_info("(vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK): %d", (vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK);
- return true;
-+ }
-
- /*
- * If we haven't found a legacy VGA device, accept a non-legacy
-@@ -651,6 +656,7 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
- * use legacy VGA resources. Prefer an integrated GPU over others.
- */
- pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-+ pr_info("cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY): %d", cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
- if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
-
- /*
-@@ -659,6 +665,7 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
- * there are more, we use the *last* because that was the
- * previous behavior.
- */
-+ pr_info("vga_arb_integrated_gpu(&pdev->dev): %d", vga_arb_integrated_gpu(&pdev->dev));
- if (vga_arb_integrated_gpu(&pdev->dev))
- return true;
-
-@@ -669,8 +676,9 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
- if (boot_vga) {
- pci_read_config_word(boot_vga->pdev, PCI_COMMAND,
- &boot_cmd);
-- if (boot_cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
-- return false;
-+ if (boot_cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)){
-+ pr_info("boot_cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY): %d", boot_cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
-+ return false;}
- }
- return true;
- }
-@@ -679,6 +687,7 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
- * Vgadev has neither IO nor MEM enabled. If we haven't found any
- * other VGA devices, it is the best candidate so far.
- */
-+ pr_info("end-of-func: boot_vga: %d", boot_vga);
- if (!boot_vga)
- return true;
-
-diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
-index c95a056ed764..c05fa72aee4f 100644
---- a/sound/pci/hda/patch_realtek.c
-+++ b/sound/pci/hda/patch_realtek.c
-@@ -10642,7 +10642,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
- SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
- SND_PCI_QUIRK(0x1043, 0x1e63, "ASUS H7606W", ALC285_FIXUP_CS35L56_I2C_2),
-- SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_CS35L56_I2C_2),
-+ SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC),
- SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
- SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0018-hid-asus-ally-add-gamepad-mode-selection.patch b/packages/l/linux-current/files/patches/hardware/asus/0018-hid-asus-ally-add-gamepad-mode-selection.patch
new file mode 100644
index 00000000000..79f65d3eb59
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0018-hid-asus-ally-add-gamepad-mode-selection.patch
@@ -0,0 +1,117 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Fri, 25 Oct 2024 08:56:54 +0200
+Subject: [PATCH 18/27] hid-asus-ally: add gamepad mode selection
+
+---
+ drivers/hid/hid-asus-ally.c | 73 +++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-asus-ally.h | 2 +
+ 2 files changed, 75 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 56cc7abc397f..7cecdc10ba2c 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -644,9 +644,82 @@ static ssize_t btn_mapping_reset_store(struct device *dev, struct device_attribu
+ }
+ ALLY_DEVICE_ATTR_WO(btn_mapping_reset, reset_btn_mapping);
+
++/* GAMEPAD MODE */
++static ssize_t _gamepad_set_mode(struct hid_device *hdev, struct ally_gamepad_cfg *ally_cfg,
++ int val)
++{
++ u8 *hidbuf;
++ int ret;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ hidbuf[2] = xpad_cmd_set_mode;
++ hidbuf[3] = xpad_cmd_len_mode;
++ hidbuf[4] = val;
++
++ ret = ally_gamepad_check_ready(hdev);
++ if (ret < 0)
++ goto report_fail;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ goto report_fail;
++
++ ret = _gamepad_apply_all(hdev, ally_cfg);
++ if (ret < 0)
++ goto report_fail;
++
++report_fail:
++ kfree(hidbuf);
++ return ret;
++}
++
++static ssize_t gamepad_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++
++ if (!drvdata.gamepad_cfg)
++ return -ENODEV;
++
++ return sysfs_emit(buf, "%d\n", ally_cfg->mode);
++}
++
++static ssize_t gamepad_mode_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct hid_device *hdev = to_hid_device(dev);
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++ int ret, val;
++
++ if (!drvdata.gamepad_cfg)
++ return -ENODEV;
++
++ ret = kstrtoint(buf, 0, &val);
++ if (ret)
++ return ret;
++
++ if (val < xpad_mode_game || val > xpad_mode_mouse)
++ return -EINVAL;
++
++ ally_cfg->mode = val;
++
++ ret = _gamepad_set_mode(hdev, ally_cfg, val);
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++
++DEVICE_ATTR_RW(gamepad_mode);
++
+ /* ROOT LEVEL ATTRS *******************************************************************************/
+ static struct attribute *gamepad_device_attrs[] = {
+ &dev_attr_btn_mapping_reset.attr,
++ &dev_attr_gamepad_mode.attr,
+ &dev_attr_gamepad_apply_all.attr,
+ NULL
+ };
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index 127db570a827..caec424c52e3 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -20,6 +20,7 @@ enum xpad_mode {
+
+ /* the xpad_cmd determines which feature is set or queried */
+ enum xpad_cmd {
++ xpad_cmd_set_mode = 0x01,
+ xpad_cmd_set_mapping = 0x02,
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
+@@ -27,6 +28,7 @@ enum xpad_cmd {
+
+ /* the xpad_cmd determines which feature is set or queried */
+ enum xpad_cmd_len {
++ xpad_cmd_len_mode = 0x01,
+ xpad_cmd_len_mapping = 0x2c,
+ xpad_cmd_len_leds = 0x0C,
+ };
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0019-hid-asus-ally-Turbo-settings-for-buttons.patch b/packages/l/linux-current/files/patches/hardware/asus/0019-hid-asus-ally-Turbo-settings-for-buttons.patch
new file mode 100644
index 00000000000..fb68d62ee52
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0019-hid-asus-ally-Turbo-settings-for-buttons.patch
@@ -0,0 +1,216 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sat, 5 Oct 2024 15:40:09 +1300
+Subject: [PATCH 19/27] hid-asus-ally: Turbo settings for buttons
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 80 ++++++++++++++++++++++++++++---------
+ drivers/hid/hid-asus-ally.h | 58 ++++++++++++++++++++++++++-
+ 2 files changed, 118 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 7cecdc10ba2c..7f0000a2db3c 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -233,6 +233,7 @@ static const char* btn_to_name(u64 key)
+ struct btn_data {
+ u64 button;
+ u64 macro;
++ bool turbo;
+ };
+
+ struct btn_mapping {
+@@ -527,6 +528,46 @@ static int _gamepad_apply_btn_pair(struct hid_device *hdev, struct ally_gamepad_
+ return ret;
+ }
+
++static int _gamepad_apply_turbo(struct hid_device *hdev, struct ally_gamepad_cfg *ally_cfg)
++{
++ struct btn_mapping *map = &ally_cfg->key_mapping[ally_cfg->mode - 1];
++ u8 *hidbuf;
++ int ret;
++
++ /* set turbo */
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ hidbuf[2] = xpad_cmd_set_turbo;
++ hidbuf[3] = xpad_cmd_len_turbo;
++
++ hidbuf[4] = map->dpad_up.turbo;
++ hidbuf[6] = map->dpad_down.turbo;
++ hidbuf[8] = map->dpad_left.turbo;
++ hidbuf[10] = map->dpad_right.turbo;
++
++ hidbuf[12] = map->btn_ls.turbo;
++ hidbuf[14] = map->btn_rs.turbo;
++ hidbuf[16] = map->btn_lb.turbo;
++ hidbuf[18] = map->btn_rb.turbo;
++
++ hidbuf[20] = map->btn_a.turbo;
++ hidbuf[22] = map->btn_b.turbo;
++ hidbuf[24] = map->btn_x.turbo;
++ hidbuf[26] = map->btn_y.turbo;
++
++ hidbuf[28] = map->btn_lt.turbo;
++ hidbuf[30] = map->btn_rt.turbo;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++
++ kfree(hidbuf);
++
++ return ret;
++}
++
+ static ssize_t _gamepad_apply_all(struct hid_device *hdev, struct ally_gamepad_cfg *ally_cfg)
+ {
+ int ret;
+@@ -556,6 +597,9 @@ static ssize_t _gamepad_apply_all(struct hid_device *hdev, struct ally_gamepad_c
+ if (ret < 0)
+ return ret;
+ ret = _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_lt_rt);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_turbo(hdev, ally_cfg);
+ if (ret < 0)
+ return ret;
+
+@@ -581,24 +625,24 @@ static ssize_t gamepad_apply_all_store(struct device *dev, struct device_attribu
+ ALLY_DEVICE_ATTR_WO(gamepad_apply_all, apply_all);
+
+ /* button map attributes, regular and macro*/
+-ALLY_BTN_MAPPING(m1, btn_m1);
+-ALLY_BTN_MAPPING(m2, btn_m2);
+-ALLY_BTN_MAPPING(a, btn_a);
+-ALLY_BTN_MAPPING(b, btn_b);
+-ALLY_BTN_MAPPING(x, btn_x);
+-ALLY_BTN_MAPPING(y, btn_y);
+-ALLY_BTN_MAPPING(lb, btn_lb);
+-ALLY_BTN_MAPPING(rb, btn_rb);
+-ALLY_BTN_MAPPING(ls, btn_ls);
+-ALLY_BTN_MAPPING(rs, btn_rs);
+-ALLY_BTN_MAPPING(lt, btn_lt);
+-ALLY_BTN_MAPPING(rt, btn_rt);
+-ALLY_BTN_MAPPING(dpad_u, dpad_up);
+-ALLY_BTN_MAPPING(dpad_d, dpad_down);
+-ALLY_BTN_MAPPING(dpad_l, dpad_left);
+-ALLY_BTN_MAPPING(dpad_r, dpad_right);
+-ALLY_BTN_MAPPING(view, btn_view);
+-ALLY_BTN_MAPPING(menu, btn_menu);
++ALLY_BTN_MAPPING_NO_TURBO(m1, btn_m1);
++ALLY_BTN_MAPPING_NO_TURBO(m2, btn_m2);
++ALLY_BTN_MAPPING_NO_TURBO(view, btn_view);
++ALLY_BTN_MAPPING_NO_TURBO(menu, btn_menu);
++ALLY_BTN_MAPPING_WITH_TURBO(a, btn_a);
++ALLY_BTN_MAPPING_WITH_TURBO(b, btn_b);
++ALLY_BTN_MAPPING_WITH_TURBO(x, btn_x);
++ALLY_BTN_MAPPING_WITH_TURBO(y, btn_y);
++ALLY_BTN_MAPPING_WITH_TURBO(lb, btn_lb);
++ALLY_BTN_MAPPING_WITH_TURBO(rb, btn_rb);
++ALLY_BTN_MAPPING_WITH_TURBO(ls, btn_ls);
++ALLY_BTN_MAPPING_WITH_TURBO(rs, btn_rs);
++ALLY_BTN_MAPPING_WITH_TURBO(lt, btn_lt);
++ALLY_BTN_MAPPING_WITH_TURBO(rt, btn_rt);
++ALLY_BTN_MAPPING_WITH_TURBO(dpad_u, dpad_up);
++ALLY_BTN_MAPPING_WITH_TURBO(dpad_d, dpad_down);
++ALLY_BTN_MAPPING_WITH_TURBO(dpad_l, dpad_left);
++ALLY_BTN_MAPPING_WITH_TURBO(dpad_r, dpad_right);
+
+ static void _gamepad_set_xpad_default(struct ally_gamepad_cfg *ally_cfg)
+ {
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index caec424c52e3..4e60e4c8f6d9 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -24,6 +24,7 @@ enum xpad_cmd {
+ xpad_cmd_set_mapping = 0x02,
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
++ xpad_cmd_set_turbo = 0x0F,
+ };
+
+ /* the xpad_cmd determines which feature is set or queried */
+@@ -31,6 +32,7 @@ enum xpad_cmd_len {
+ xpad_cmd_len_mode = 0x01,
+ xpad_cmd_len_mapping = 0x2c,
+ xpad_cmd_len_leds = 0x0C,
++ xpad_cmd_len_turbo = 0x20,
+ };
+
+ /* Values correspond to the actual HID byte value required */
+@@ -228,6 +230,37 @@ enum btn_pair_index {
+ return count; \
+ }
+
++#define ALLY_TURBO_SHOW(_fname, _btn_name) \
++ static ssize_t _fname##_show(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ struct btn_data *btn; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ btn = &ally_cfg->key_mapping[ally_cfg->mode - 1]._btn_name; \
++ return sysfs_emit(buf, "%d\n", btn->turbo); \
++ }
++
++#define ALLY_TURBO_STORE(_fname, _btn_name) \
++ static ssize_t _fname##_store(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ struct btn_data *btn; \
++ bool turbo; \
++ int ret; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ btn = &ally_cfg->key_mapping[ally_cfg->mode - 1]._btn_name; \
++ ret = kstrtobool(buf, &turbo); \
++ if (ret) \
++ return ret; \
++ btn->turbo = turbo; \
++ return count; \
++ }
++
+ #define ALLY_BTN_ATTRS_GROUP(_name, _fname) \
+ static struct attribute *_fname##_attrs[] = { \
+ &dev_attr_##_fname.attr, \
+@@ -238,11 +271,32 @@ enum btn_pair_index {
+ .attrs = _fname##_attrs, \
+ }
+
+-#define ALLY_BTN_MAPPING(_fname, _mname) \
++#define ALLY_BTN_ATTRS_GROUP_WITH_TURBO(_name, _fname) \
++ static struct attribute *_fname##_attrs[] = { \
++ &dev_attr_##_fname.attr, \
++ &dev_attr_##_fname##_macro.attr, \
++ &dev_attr_##_fname##_turbo.attr, \
++ }; \
++ static const struct attribute_group _fname##_attr_group = { \
++ .name = __stringify(_name), \
++ .attrs = _fname##_attrs, \
++ }
++
++#define _ALLY_BTN_MAPPING(_fname, _mname) \
+ ALLY_BTN_SHOW(btn_mapping_##_fname, _mname, false); \
+ ALLY_BTN_STORE(btn_mapping_##_fname, _mname, false); \
+ ALLY_BTN_SHOW(btn_mapping_##_fname##_macro, _mname, true); \
+ ALLY_BTN_STORE(btn_mapping_##_fname##_macro, _mname, true); \
+ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname, remap); \
+- ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname##_macro, macro_remap); \
++ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname##_macro, macro_remap);
++
++#define ALLY_BTN_MAPPING_NO_TURBO(_fname, _mname) \
++ _ALLY_BTN_MAPPING(_fname, _mname) \
+ ALLY_BTN_ATTRS_GROUP(btn_##_fname, btn_mapping_##_fname)
++
++#define ALLY_BTN_MAPPING_WITH_TURBO(_fname, _mname) \
++ _ALLY_BTN_MAPPING(_fname, _mname) \
++ ALLY_TURBO_SHOW(btn_mapping_##_fname##_turbo, _mname); \
++ ALLY_TURBO_STORE(btn_mapping_##_fname##_turbo, _mname); \
++ ALLY_DEVICE_ATTR_RW(btn_mapping_##_fname##_turbo, turbo); \
++ ALLY_BTN_ATTRS_GROUP_WITH_TURBO(btn_##_fname, btn_mapping_##_fname)
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0020-hid-asus-ally-add-vibration-intensity-settings.patch b/packages/l/linux-current/files/patches/hardware/asus/0020-hid-asus-ally-add-vibration-intensity-settings.patch
new file mode 100644
index 00000000000..f1adef72ba8
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0020-hid-asus-ally-add-vibration-intensity-settings.patch
@@ -0,0 +1,167 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sat, 5 Oct 2024 20:46:00 +1300
+Subject: [PATCH 20/27] hid-asus-ally: add vibration intensity settings
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 93 +++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-asus-ally.h | 6 +++
+ 2 files changed, 99 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 7f0000a2db3c..cdc45e2c79b4 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -267,6 +267,11 @@ struct ally_gamepad_cfg {
+ * index: [mode]
+ */
+ struct btn_mapping key_mapping[xpad_mode_mouse];
++ /*
++ * index: left, right
++ * max: 64
++ */
++ u8 vibration_intensity[2];
+ };
+
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+@@ -438,6 +443,89 @@ static int ally_gamepad_check_ready(struct hid_device *hdev)
+ return ret;
+ }
+
++/* VIBRATION INTENSITY ****************************************************************************/
++static ssize_t gamepad_vibration_intensity_index_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return sysfs_emit(buf, "left right\n");
++}
++
++ALLY_DEVICE_ATTR_RO(gamepad_vibration_intensity_index, vibration_intensity_index);
++
++static ssize_t _gamepad_apply_intensity(struct hid_device *hdev,
++ struct ally_gamepad_cfg *ally_cfg)
++{
++ u8 *hidbuf;
++ int ret;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ hidbuf[2] = xpad_cmd_set_vibe_intensity;
++ hidbuf[3] = xpad_cmd_len_vibe_intensity;
++ hidbuf[4] = ally_cfg->vibration_intensity[0];
++ hidbuf[5] = ally_cfg->vibration_intensity[1];
++
++ ret = ally_gamepad_check_ready(hdev);
++ if (ret < 0)
++ goto report_fail;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ goto report_fail;
++
++report_fail:
++ kfree(hidbuf);
++ return ret;
++}
++
++static ssize_t gamepad_vibration_intensity_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++
++ if (!drvdata.gamepad_cfg)
++ return -ENODEV;
++
++ return sysfs_emit(
++ buf, "%d %d\n",
++ ally_cfg->vibration_intensity[0],
++ ally_cfg->vibration_intensity[1]);
++}
++
++static ssize_t gamepad_vibration_intensity_store(struct device *dev,
++ struct device_attribute *attr, const char *buf,
++ size_t count)
++{
++ struct hid_device *hdev = to_hid_device(dev);
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++ u32 left, right;
++ int ret;
++
++ if (!drvdata.gamepad_cfg)
++ return -ENODEV;
++
++ if (sscanf(buf, "%d %d", &left, &right) != 2)
++ return -EINVAL;
++
++ if (left > 64 || right > 64)
++ return -EINVAL;
++
++ ally_cfg->vibration_intensity[0] = left;
++ ally_cfg->vibration_intensity[1] = right;
++
++ ret = _gamepad_apply_intensity(hdev, ally_cfg);
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++
++ALLY_DEVICE_ATTR_RW(gamepad_vibration_intensity, vibration_intensity);
++
+ /* A HID packet conatins mappings for two buttons: btn1, btn1_macro, btn2, btn2_macro */
+ static void _btn_pair_to_hid_pkt(struct ally_gamepad_cfg *ally_cfg,
+ enum btn_pair_index pair,
+@@ -765,6 +853,8 @@ static struct attribute *gamepad_device_attrs[] = {
+ &dev_attr_btn_mapping_reset.attr,
+ &dev_attr_gamepad_mode.attr,
+ &dev_attr_gamepad_apply_all.attr,
++ &dev_attr_gamepad_vibration_intensity.attr,
++ &dev_attr_gamepad_vibration_intensity_index.attr,
+ NULL
+ };
+
+@@ -837,6 +927,9 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+ ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m2.button = BTN_KB_M2;
+ _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_m1_m2);
+
++ ally_cfg->vibration_intensity[0] = 0x64;
++ ally_cfg->vibration_intensity[1] = 0x64;
++
+ drvdata.gamepad_cfg = ally_cfg; // Must asign before attr group setup
+ if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {
+ err = -ENODEV;
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index 4e60e4c8f6d9..eea4696850fa 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -22,6 +22,7 @@ enum xpad_mode {
+ enum xpad_cmd {
+ xpad_cmd_set_mode = 0x01,
+ xpad_cmd_set_mapping = 0x02,
++ xpad_cmd_set_vibe_intensity = 0x06,
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
+ xpad_cmd_set_turbo = 0x0F,
+@@ -31,6 +32,7 @@ enum xpad_cmd {
+ enum xpad_cmd_len {
+ xpad_cmd_len_mode = 0x01,
+ xpad_cmd_len_mapping = 0x2c,
++ xpad_cmd_len_vibe_intensity = 0x02,
+ xpad_cmd_len_leds = 0x0C,
+ xpad_cmd_len_turbo = 0x20,
+ };
+@@ -196,6 +198,10 @@ enum btn_pair_index {
+ struct device_attribute dev_attr_##_name = \
+ __ATTR(_sysfs_name, 0644, _name##_show, _name##_store)
+
++#define ALLY_DEVICE_ATTR_RO(_name, _sysfs_name) \
++ struct device_attribute dev_attr_##_name = \
++ __ATTR(_sysfs_name, 0444, _name##_show, NULL)
++
+ /* button specific macros */
+ #define ALLY_BTN_SHOW(_fname, _btn_name, _secondary) \
+ static ssize_t _fname##_show(struct device *dev, \
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0021-hid-asus-ally-add-JS-deadzones.patch b/packages/l/linux-current/files/patches/hardware/asus/0021-hid-asus-ally-add-JS-deadzones.patch
new file mode 100644
index 00000000000..d492e67197b
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0021-hid-asus-ally-add-JS-deadzones.patch
@@ -0,0 +1,205 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sat, 5 Oct 2024 21:32:41 +1300
+Subject: [PATCH 21/27] hid-asus-ally: add JS deadzones
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 84 +++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-asus-ally.h | 39 +++++++++++++++++
+ 2 files changed, 123 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index cdc45e2c79b4..9bb9ac3ce87b 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -257,6 +257,11 @@ struct btn_mapping {
+ struct btn_data btn_m2;
+ };
+
++struct deadzone {
++ u8 inner;
++ u8 outer;
++};
++
+ /* ROG Ally has many settings related to the gamepad, all using the same n-key endpoint */
+ struct ally_gamepad_cfg {
+ struct hid_device *hdev;
+@@ -272,6 +277,10 @@ struct ally_gamepad_cfg {
+ * max: 64
+ */
+ u8 vibration_intensity[2];
++
++ /* deadzones */
++ struct deadzone ls_dz; // left stick
++ struct deadzone rs_dz; // right stick
+ };
+
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+@@ -526,6 +535,75 @@ static ssize_t gamepad_vibration_intensity_store(struct device *dev,
+
+ ALLY_DEVICE_ATTR_RW(gamepad_vibration_intensity, vibration_intensity);
+
++/* ANALOGUE DEADZONES *****************************************************************************/
++static ssize_t _gamepad_apply_deadzones(struct hid_device *hdev,
++ struct ally_gamepad_cfg *ally_cfg)
++{
++ u8 *hidbuf;
++ int ret;
++
++ ret = ally_gamepad_check_ready(hdev);
++ if (ret < 0)
++ return ret;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ hidbuf[2] = xpad_cmd_set_js_dz;
++ hidbuf[3] = xpad_cmd_len_deadzone;
++ hidbuf[4] = ally_cfg->ls_dz.inner;
++ hidbuf[5] = ally_cfg->ls_dz.outer;
++ hidbuf[6] = ally_cfg->rs_dz.inner;
++ hidbuf[7] = ally_cfg->rs_dz.outer;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++
++ kfree(hidbuf);
++ return ret;
++}
++
++static void _gamepad_set_deadzones_default(struct ally_gamepad_cfg *ally_cfg)
++{
++ ally_cfg->ls_dz.inner = 0x00;
++ ally_cfg->ls_dz.outer = 0x64;
++ ally_cfg->rs_dz.inner = 0x00;
++ ally_cfg->rs_dz.outer = 0x64;
++}
++
++static ssize_t axis_xyz_deadzone_index_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ return sysfs_emit(buf, "inner outer\n");
++}
++
++ALLY_DEVICE_ATTR_RO(axis_xyz_deadzone_index, deadzone_index);
++
++ALLY_DEADZONES(axis_xy_left, ls_dz);
++ALLY_DEADZONES(axis_xy_right, rs_dz);
++
++static struct attribute *axis_xy_left_attrs[] = {
++ &dev_attr_axis_xy_left_deadzone.attr,
++ &dev_attr_axis_xyz_deadzone_index.attr,
++ NULL
++};
++static const struct attribute_group axis_xy_left_attr_group = {
++ .name = "axis_xy_left",
++ .attrs = axis_xy_left_attrs,
++};
++
++static struct attribute *axis_xy_right_attrs[] = {
++ &dev_attr_axis_xy_right_deadzone.attr,
++ &dev_attr_axis_xyz_deadzone_index.attr,
++ NULL
++};
++static const struct attribute_group axis_xy_right_attr_group = {
++ .name = "axis_xy_right",
++ .attrs = axis_xy_right_attrs,
++};
++
+ /* A HID packet conatins mappings for two buttons: btn1, btn1_macro, btn2, btn2_macro */
+ static void _btn_pair_to_hid_pkt(struct ally_gamepad_cfg *ally_cfg,
+ enum btn_pair_index pair,
+@@ -688,6 +766,9 @@ static ssize_t _gamepad_apply_all(struct hid_device *hdev, struct ally_gamepad_c
+ if (ret < 0)
+ return ret;
+ ret = _gamepad_apply_turbo(hdev, ally_cfg);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_deadzones(hdev, ally_cfg);
+ if (ret < 0)
+ return ret;
+
+@@ -864,6 +945,8 @@ static const struct attribute_group ally_controller_attr_group = {
+
+ static const struct attribute_group *gamepad_device_attr_groups[] = {
+ &ally_controller_attr_group,
++ &axis_xy_left_attr_group,
++ &axis_xy_right_attr_group,
+ &btn_mapping_m1_attr_group,
+ &btn_mapping_m2_attr_group,
+ &btn_mapping_a_attr_group,
+@@ -929,6 +1012,7 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+
+ ally_cfg->vibration_intensity[0] = 0x64;
+ ally_cfg->vibration_intensity[1] = 0x64;
++ _gamepad_set_deadzones_default(ally_cfg);
+
+ drvdata.gamepad_cfg = ally_cfg; // Must asign before attr group setup
+ if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index eea4696850fa..76ba5fcd593a 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -22,6 +22,7 @@ enum xpad_mode {
+ enum xpad_cmd {
+ xpad_cmd_set_mode = 0x01,
+ xpad_cmd_set_mapping = 0x02,
++ xpad_cmd_set_js_dz = 0x04, /* deadzones */
+ xpad_cmd_set_vibe_intensity = 0x06,
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
+@@ -32,6 +33,7 @@ enum xpad_cmd {
+ enum xpad_cmd_len {
+ xpad_cmd_len_mode = 0x01,
+ xpad_cmd_len_mapping = 0x2c,
++ xpad_cmd_len_deadzone = 0x04,
+ xpad_cmd_len_vibe_intensity = 0x02,
+ xpad_cmd_len_leds = 0x0C,
+ xpad_cmd_len_turbo = 0x20,
+@@ -267,6 +269,43 @@ enum btn_pair_index {
+ return count; \
+ }
+
++#define ALLY_DEADZONE_SHOW(_fname, _axis_name) \
++ static ssize_t _fname##_show(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ struct deadzone *dz; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ dz = &ally_cfg->_axis_name; \
++ return sysfs_emit(buf, "%d %d\n", dz->inner, dz->outer); \
++ }
++
++#define ALLY_DEADZONE_STORE(_fname, _axis_name) \
++ static ssize_t _fname##_store(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ struct hid_device *hdev = to_hid_device(dev); \
++ u32 inner, outer; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ if (sscanf(buf, "%d %d", &inner, &outer) != 2) \
++ return -EINVAL; \
++ if (inner > 64 || outer > 64 || inner > outer) \
++ return -EINVAL; \
++ ally_cfg->_axis_name.inner = inner; \
++ ally_cfg->_axis_name.outer = outer; \
++ _gamepad_apply_deadzones(hdev, ally_cfg); \
++ return count; \
++ }
++
++#define ALLY_DEADZONES(_fname, _mname) \
++ ALLY_DEADZONE_SHOW(_fname##_deadzone, _mname); \
++ ALLY_DEADZONE_STORE(_fname##_deadzone, _mname); \
++ ALLY_DEVICE_ATTR_RW(_fname##_deadzone, deadzone)
++
+ #define ALLY_BTN_ATTRS_GROUP(_name, _fname) \
+ static struct attribute *_fname##_attrs[] = { \
+ &dev_attr_##_fname.attr, \
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0022-hid-asus-ally-add-trigger-deadzones.patch b/packages/l/linux-current/files/patches/hardware/asus/0022-hid-asus-ally-add-trigger-deadzones.patch
new file mode 100644
index 00000000000..e99035b5219
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0022-hid-asus-ally-add-trigger-deadzones.patch
@@ -0,0 +1,113 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sat, 5 Oct 2024 21:37:27 +1300
+Subject: [PATCH 22/27] hid-asus-ally: add trigger deadzones
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 43 +++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-asus-ally.h | 1 +
+ 2 files changed, 44 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 9bb9ac3ce87b..2e34cb47972e 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -281,6 +281,8 @@ struct ally_gamepad_cfg {
+ /* deadzones */
+ struct deadzone ls_dz; // left stick
+ struct deadzone rs_dz; // right stick
++ struct deadzone lt_dz; // left trigger
++ struct deadzone rt_dz; // right trigger
+ };
+
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+@@ -560,7 +562,20 @@ static ssize_t _gamepad_apply_deadzones(struct hid_device *hdev,
+ hidbuf[7] = ally_cfg->rs_dz.outer;
+
+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ goto end;
++
++ hidbuf[2] = xpad_cmd_set_tr_dz;
++ hidbuf[4] = ally_cfg->lt_dz.inner;
++ hidbuf[5] = ally_cfg->lt_dz.outer;
++ hidbuf[6] = ally_cfg->rt_dz.inner;
++ hidbuf[7] = ally_cfg->rt_dz.outer;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ goto end;
+
++end:
+ kfree(hidbuf);
+ return ret;
+ }
+@@ -571,6 +586,10 @@ static void _gamepad_set_deadzones_default(struct ally_gamepad_cfg *ally_cfg)
+ ally_cfg->ls_dz.outer = 0x64;
+ ally_cfg->rs_dz.inner = 0x00;
+ ally_cfg->rs_dz.outer = 0x64;
++ ally_cfg->lt_dz.inner = 0x00;
++ ally_cfg->lt_dz.outer = 0x64;
++ ally_cfg->rt_dz.inner = 0x00;
++ ally_cfg->rt_dz.outer = 0x64;
+ }
+
+ static ssize_t axis_xyz_deadzone_index_show(struct device *dev, struct device_attribute *attr,
+@@ -583,6 +602,8 @@ ALLY_DEVICE_ATTR_RO(axis_xyz_deadzone_index, deadzone_index);
+
+ ALLY_DEADZONES(axis_xy_left, ls_dz);
+ ALLY_DEADZONES(axis_xy_right, rs_dz);
++ALLY_DEADZONES(axis_z_left, lt_dz);
++ALLY_DEADZONES(axis_z_right, rt_dz);
+
+ static struct attribute *axis_xy_left_attrs[] = {
+ &dev_attr_axis_xy_left_deadzone.attr,
+@@ -604,6 +625,26 @@ static const struct attribute_group axis_xy_right_attr_group = {
+ .attrs = axis_xy_right_attrs,
+ };
+
++static struct attribute *axis_z_left_attrs[] = {
++ &dev_attr_axis_z_left_deadzone.attr,
++ &dev_attr_axis_xyz_deadzone_index.attr,
++ NULL,
++};
++static const struct attribute_group axis_z_left_attr_group = {
++ .name = "axis_z_left",
++ .attrs = axis_z_left_attrs,
++};
++
++static struct attribute *axis_z_right_attrs[] = {
++ &dev_attr_axis_z_right_deadzone.attr,
++ &dev_attr_axis_xyz_deadzone_index.attr,
++ NULL,
++};
++static const struct attribute_group axis_z_right_attr_group = {
++ .name = "axis_z_right",
++ .attrs = axis_z_right_attrs,
++};
++
+ /* A HID packet conatins mappings for two buttons: btn1, btn1_macro, btn2, btn2_macro */
+ static void _btn_pair_to_hid_pkt(struct ally_gamepad_cfg *ally_cfg,
+ enum btn_pair_index pair,
+@@ -947,6 +988,8 @@ static const struct attribute_group *gamepad_device_attr_groups[] = {
+ &ally_controller_attr_group,
+ &axis_xy_left_attr_group,
+ &axis_xy_right_attr_group,
++ &axis_z_left_attr_group,
++ &axis_z_right_attr_group,
+ &btn_mapping_m1_attr_group,
+ &btn_mapping_m2_attr_group,
+ &btn_mapping_a_attr_group,
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index 76ba5fcd593a..f103b5ecff36 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -23,6 +23,7 @@ enum xpad_cmd {
+ xpad_cmd_set_mode = 0x01,
+ xpad_cmd_set_mapping = 0x02,
+ xpad_cmd_set_js_dz = 0x04, /* deadzones */
++ xpad_cmd_set_tr_dz = 0x05, /* deadzones */
+ xpad_cmd_set_vibe_intensity = 0x06,
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0023-hid-asus-ally-add-anti-deadzones.patch b/packages/l/linux-current/files/patches/hardware/asus/0023-hid-asus-ally-add-anti-deadzones.patch
new file mode 100644
index 00000000000..e7af998ebf5
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0023-hid-asus-ally-add-anti-deadzones.patch
@@ -0,0 +1,181 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sun, 6 Oct 2024 19:49:24 +1300
+Subject: [PATCH 23/27] hid-asus-ally: add anti-deadzones
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 110 ++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-asus-ally.h | 2 +
+ 2 files changed, 112 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 2e34cb47972e..3e4d9b19dc41 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -283,6 +283,9 @@ struct ally_gamepad_cfg {
+ struct deadzone rs_dz; // right stick
+ struct deadzone lt_dz; // left trigger
+ struct deadzone rt_dz; // right trigger
++ /* anti-deadzones */
++ u8 ls_adz; // left stick
++ u8 rs_adz; // right stick
+ };
+
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+@@ -605,7 +608,109 @@ ALLY_DEADZONES(axis_xy_right, rs_dz);
+ ALLY_DEADZONES(axis_z_left, lt_dz);
+ ALLY_DEADZONES(axis_z_right, rt_dz);
+
++/* ANTI-DEADZONES *********************************************************************************/
++static ssize_t _gamepad_apply_js_ADZ(struct hid_device *hdev,
++ struct ally_gamepad_cfg *ally_cfg)
++{
++ u8 *hidbuf;
++ int ret;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ hidbuf[2] = xpad_cmd_set_adz;
++ hidbuf[3] = xpad_cmd_len_adz;
++ hidbuf[4] = ally_cfg->ls_adz;
++ hidbuf[5] = ally_cfg->rs_adz;
++
++ ret = ally_gamepad_check_ready(hdev);
++ if (ret < 0)
++ goto report_fail;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ goto report_fail;
++
++report_fail:
++ kfree(hidbuf);
++ return ret;
++}
++
++static void _gamepad_set_anti_deadzones_default(struct ally_gamepad_cfg *ally_cfg)
++{
++ ally_cfg->ls_adz = 0x00;
++ ally_cfg->rs_adz = 0x00;
++}
++
++static ssize_t _gamepad_js_ADZ_store(struct device *dev, const char *buf, u8 *adz)
++{
++ int ret, val;
++
++ ret = kstrtoint(buf, 0, &val);
++ if (ret)
++ return ret;
++
++ if (val < 0 || val > 32)
++ return -EINVAL;
++
++ *adz = val;
++
++ return ret;
++}
++
++static ssize_t axis_xy_left_anti_deadzone_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++
++ return sysfs_emit(buf, "%d\n", ally_cfg->ls_adz);
++}
++
++static ssize_t axis_xy_left_anti_deadzone_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++ int ret;
++
++ ret = _gamepad_js_ADZ_store(dev, buf, &ally_cfg->ls_adz);
++ if (ret)
++ return ret;
++
++ return count;
++}
++ALLY_DEVICE_ATTR_RW(axis_xy_left_anti_deadzone, anti_deadzone);
++
++static ssize_t axis_xy_right_anti_deadzone_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++
++ return sysfs_emit(buf, "%d\n", ally_cfg->rs_adz);
++}
++
++static ssize_t axis_xy_right_anti_deadzone_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++ int ret;
++
++ ret = _gamepad_js_ADZ_store(dev, buf, &ally_cfg->rs_adz);
++ if (ret)
++ return ret;
++
++ return count;
++}
++ALLY_DEVICE_ATTR_RW(axis_xy_right_anti_deadzone, anti_deadzone);
++
+ static struct attribute *axis_xy_left_attrs[] = {
++ &dev_attr_axis_xy_left_anti_deadzone.attr,
+ &dev_attr_axis_xy_left_deadzone.attr,
+ &dev_attr_axis_xyz_deadzone_index.attr,
+ NULL
+@@ -616,6 +721,7 @@ static const struct attribute_group axis_xy_left_attr_group = {
+ };
+
+ static struct attribute *axis_xy_right_attrs[] = {
++ &dev_attr_axis_xy_right_anti_deadzone.attr,
+ &dev_attr_axis_xy_right_deadzone.attr,
+ &dev_attr_axis_xyz_deadzone_index.attr,
+ NULL
+@@ -810,6 +916,9 @@ static ssize_t _gamepad_apply_all(struct hid_device *hdev, struct ally_gamepad_c
+ if (ret < 0)
+ return ret;
+ ret = _gamepad_apply_deadzones(hdev, ally_cfg);
++ if (ret < 0)
++ return ret;
++ ret = _gamepad_apply_js_ADZ(hdev, ally_cfg);
+ if (ret < 0)
+ return ret;
+
+@@ -1056,6 +1165,7 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+ ally_cfg->vibration_intensity[0] = 0x64;
+ ally_cfg->vibration_intensity[1] = 0x64;
+ _gamepad_set_deadzones_default(ally_cfg);
++ _gamepad_set_anti_deadzones_default(ally_cfg);
+
+ drvdata.gamepad_cfg = ally_cfg; // Must asign before attr group setup
+ if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index f103b5ecff36..9c13de73749c 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -28,6 +28,7 @@ enum xpad_cmd {
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
+ xpad_cmd_set_turbo = 0x0F,
++ xpad_cmd_set_adz = 0x18,
+ };
+
+ /* the xpad_cmd determines which feature is set or queried */
+@@ -38,6 +39,7 @@ enum xpad_cmd_len {
+ xpad_cmd_len_vibe_intensity = 0x02,
+ xpad_cmd_len_leds = 0x0C,
+ xpad_cmd_len_turbo = 0x20,
++ xpad_cmd_len_adz = 0x02,
+ };
+
+ /* Values correspond to the actual HID byte value required */
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0024-hid-asus-ally-add-JS-response-curves.patch b/packages/l/linux-current/files/patches/hardware/asus/0024-hid-asus-ally-add-JS-response-curves.patch
new file mode 100644
index 00000000000..dc048573331
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0024-hid-asus-ally-add-JS-response-curves.patch
@@ -0,0 +1,236 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Sun, 6 Oct 2024 21:22:40 +1300
+Subject: [PATCH 24/27] hid-asus-ally: add JS response curves
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 103 ++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-asus-ally.h | 38 +++++++++++++
+ 2 files changed, 141 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 3e4d9b19dc41..4d9954362625 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -5,8 +5,10 @@
+ * Copyright (c) 2023 Luke Jones
+ */
+
++#include "linux/compiler_attributes.h"
+ #include "linux/device.h"
+ #include "linux/pm.h"
++#include "linux/printk.h"
+ #include "linux/slab.h"
+ #include
+ #include
+@@ -262,6 +264,17 @@ struct deadzone {
+ u8 outer;
+ };
+
++struct response_curve {
++ uint8_t move_pct_1;
++ uint8_t response_pct_1;
++ uint8_t move_pct_2;
++ uint8_t response_pct_2;
++ uint8_t move_pct_3;
++ uint8_t response_pct_3;
++ uint8_t move_pct_4;
++ uint8_t response_pct_4;
++} __packed;
++
+ /* ROG Ally has many settings related to the gamepad, all using the same n-key endpoint */
+ struct ally_gamepad_cfg {
+ struct hid_device *hdev;
+@@ -286,6 +299,9 @@ struct ally_gamepad_cfg {
+ /* anti-deadzones */
+ u8 ls_adz; // left stick
+ u8 rs_adz; // right stick
++ /* joystick response curves */
++ struct response_curve ls_rc;
++ struct response_curve rs_rc;
+ };
+
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+@@ -709,10 +725,85 @@ static ssize_t axis_xy_right_anti_deadzone_store(struct device *dev,
+ }
+ ALLY_DEVICE_ATTR_RW(axis_xy_right_anti_deadzone, anti_deadzone);
+
++/* JS RESPONSE CURVES *****************************************************************************/
++static void _gamepad_set_js_response_curves_default(struct ally_gamepad_cfg *ally_cfg)
++{
++ struct response_curve *js1_rc = &ally_cfg->ls_rc;
++ struct response_curve *js2_rc = &ally_cfg->rs_rc;
++ js1_rc->move_pct_1 = js2_rc->move_pct_1 = 0x16; // 25%
++ js1_rc->move_pct_2 = js2_rc->move_pct_2 = 0x32; // 50%
++ js1_rc->move_pct_3 = js2_rc->move_pct_3 = 0x48; // 75%
++ js1_rc->move_pct_4 = js2_rc->move_pct_4 = 0x64; // 100%
++ js1_rc->response_pct_1 = js2_rc->response_pct_1 = 0x16;
++ js1_rc->response_pct_2 = js2_rc->response_pct_2 = 0x32;
++ js1_rc->response_pct_3 = js2_rc->response_pct_3 = 0x48;
++ js1_rc->response_pct_4 = js2_rc->response_pct_4 = 0x64;
++}
++
++static ssize_t _gamepad_apply_response_curves(struct hid_device *hdev,
++ struct ally_gamepad_cfg *ally_cfg)
++{
++ u8 *hidbuf;
++ int ret;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
++ memcpy(&hidbuf[2], &ally_cfg->ls_rc, sizeof(ally_cfg->ls_rc));
++
++ ret = ally_gamepad_check_ready(hdev);
++ if (ret < 0)
++ goto report_fail;
++
++ hidbuf[4] = 0x02;
++ memcpy(&hidbuf[5], &ally_cfg->rs_rc, sizeof(ally_cfg->rs_rc));
++
++ ret = ally_gamepad_check_ready(hdev);
++ if (ret < 0)
++ goto report_fail;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0)
++ goto report_fail;
++
++report_fail:
++ kfree(hidbuf);
++ return ret;
++}
++
++ALLY_JS_RC_POINT(axis_xy_left, move, 1);
++ALLY_JS_RC_POINT(axis_xy_left, move, 2);
++ALLY_JS_RC_POINT(axis_xy_left, move, 3);
++ALLY_JS_RC_POINT(axis_xy_left, move, 4);
++ALLY_JS_RC_POINT(axis_xy_left, response, 1);
++ALLY_JS_RC_POINT(axis_xy_left, response, 2);
++ALLY_JS_RC_POINT(axis_xy_left, response, 3);
++ALLY_JS_RC_POINT(axis_xy_left, response, 4);
++
++ALLY_JS_RC_POINT(axis_xy_right, move, 1);
++ALLY_JS_RC_POINT(axis_xy_right, move, 2);
++ALLY_JS_RC_POINT(axis_xy_right, move, 3);
++ALLY_JS_RC_POINT(axis_xy_right, move, 4);
++ALLY_JS_RC_POINT(axis_xy_right, response, 1);
++ALLY_JS_RC_POINT(axis_xy_right, response, 2);
++ALLY_JS_RC_POINT(axis_xy_right, response, 3);
++ALLY_JS_RC_POINT(axis_xy_right, response, 4);
++
+ static struct attribute *axis_xy_left_attrs[] = {
+ &dev_attr_axis_xy_left_anti_deadzone.attr,
+ &dev_attr_axis_xy_left_deadzone.attr,
+ &dev_attr_axis_xyz_deadzone_index.attr,
++ &dev_attr_axis_xy_left_move_1.attr,
++ &dev_attr_axis_xy_left_move_2.attr,
++ &dev_attr_axis_xy_left_move_3.attr,
++ &dev_attr_axis_xy_left_move_4.attr,
++ &dev_attr_axis_xy_left_response_1.attr,
++ &dev_attr_axis_xy_left_response_2.attr,
++ &dev_attr_axis_xy_left_response_3.attr,
++ &dev_attr_axis_xy_left_response_4.attr,
+ NULL
+ };
+ static const struct attribute_group axis_xy_left_attr_group = {
+@@ -724,6 +815,14 @@ static struct attribute *axis_xy_right_attrs[] = {
+ &dev_attr_axis_xy_right_anti_deadzone.attr,
+ &dev_attr_axis_xy_right_deadzone.attr,
+ &dev_attr_axis_xyz_deadzone_index.attr,
++ &dev_attr_axis_xy_right_move_1.attr,
++ &dev_attr_axis_xy_right_move_2.attr,
++ &dev_attr_axis_xy_right_move_3.attr,
++ &dev_attr_axis_xy_right_move_4.attr,
++ &dev_attr_axis_xy_right_response_1.attr,
++ &dev_attr_axis_xy_right_response_2.attr,
++ &dev_attr_axis_xy_right_response_3.attr,
++ &dev_attr_axis_xy_right_response_4.attr,
+ NULL
+ };
+ static const struct attribute_group axis_xy_right_attr_group = {
+@@ -919,6 +1018,9 @@ static ssize_t _gamepad_apply_all(struct hid_device *hdev, struct ally_gamepad_c
+ if (ret < 0)
+ return ret;
+ ret = _gamepad_apply_js_ADZ(hdev, ally_cfg);
++ if (ret < 0)
++ return ret;
++ ret =_gamepad_apply_response_curves(hdev, ally_cfg);
+ if (ret < 0)
+ return ret;
+
+@@ -1166,6 +1268,7 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+ ally_cfg->vibration_intensity[1] = 0x64;
+ _gamepad_set_deadzones_default(ally_cfg);
+ _gamepad_set_anti_deadzones_default(ally_cfg);
++ _gamepad_set_js_response_curves_default(ally_cfg);
+
+ drvdata.gamepad_cfg = ally_cfg; // Must asign before attr group setup
+ if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {
+diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
+index 9c13de73749c..518d8db3af5e 100644
+--- a/drivers/hid/hid-asus-ally.h
++++ b/drivers/hid/hid-asus-ally.h
+@@ -28,6 +28,7 @@ enum xpad_cmd {
+ xpad_cmd_set_leds = 0x08,
+ xpad_cmd_check_ready = 0x0A,
+ xpad_cmd_set_turbo = 0x0F,
++ xpad_cmd_set_response_curve = 0x13,
+ xpad_cmd_set_adz = 0x18,
+ };
+
+@@ -39,6 +40,7 @@ enum xpad_cmd_len {
+ xpad_cmd_len_vibe_intensity = 0x02,
+ xpad_cmd_len_leds = 0x0C,
+ xpad_cmd_len_turbo = 0x20,
++ xpad_cmd_len_response_curve = 0x09,
+ xpad_cmd_len_adz = 0x02,
+ };
+
+@@ -309,6 +311,42 @@ enum btn_pair_index {
+ ALLY_DEADZONE_STORE(_fname##_deadzone, _mname); \
+ ALLY_DEVICE_ATTR_RW(_fname##_deadzone, deadzone)
+
++/* response curve macros */
++#define ALLY_RESP_CURVE_SHOW(_fname, _mname) \
++static ssize_t _fname##_show(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ return sysfs_emit(buf, "%d\n", ally_cfg->ls_rc._mname); \
++ }
++
++#define ALLY_RESP_CURVE_STORE(_fname, _mname) \
++static ssize_t _fname##_store(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++ { \
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
++ int ret, val; \
++ if (!drvdata.gamepad_cfg) \
++ return -ENODEV; \
++ ret = kstrtoint(buf, 0, &val); \
++ if (ret) \
++ return ret; \
++ if (val < 0 || val > 100) \
++ return -EINVAL; \
++ ally_cfg->ls_rc._mname = val; \
++ return count; \
++ }
++
++/* _point_n must start at 1 */
++#define ALLY_JS_RC_POINT(_fname, _mname, _num) \
++ ALLY_RESP_CURVE_SHOW(_fname##_##_mname##_##_num, _mname##_pct_##_num); \
++ ALLY_RESP_CURVE_STORE(_fname##_##_mname##_##_num, _mname##_pct_##_num); \
++ ALLY_DEVICE_ATTR_RW(_fname##_##_mname##_##_num, curve_##_mname##_pct_##_num)
++
+ #define ALLY_BTN_ATTRS_GROUP(_name, _fname) \
+ static struct attribute *_fname##_attrs[] = { \
+ &dev_attr_##_fname.attr, \
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0025-hid-asus-ally-add-calibrations-wip.patch b/packages/l/linux-current/files/patches/hardware/asus/0025-hid-asus-ally-add-calibrations-wip.patch
new file mode 100644
index 00000000000..f9e9a8dd027
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0025-hid-asus-ally-add-calibrations-wip.patch
@@ -0,0 +1,144 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Thu, 10 Oct 2024 11:15:36 +1300
+Subject: [PATCH 25/27] hid-asus-ally: add calibrations (wip)
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/hid/hid-asus-ally.c | 95 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 95 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 4d9954362625..03603695c484 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -275,6 +275,28 @@ struct response_curve {
+ uint8_t response_pct_4;
+ } __packed;
+
++struct js_axis_calibrations {
++ uint16_t left_y_stable;
++ uint16_t left_y_min;
++ uint16_t left_y_max;
++ uint16_t left_x_stable;
++ uint16_t left_x_min;
++ uint16_t left_x_max;
++ uint16_t right_y_stable;
++ uint16_t right_y_min;
++ uint16_t right_y_max;
++ uint16_t right_x_stable;
++ uint16_t right_x_min;
++ uint16_t right_x_max;
++} __packed;
++
++struct tr_axis_calibrations {
++ uint16_t left_stable;
++ uint16_t left_max;
++ uint16_t right_stable;
++ uint16_t right_max;
++} __packed;
++
+ /* ROG Ally has many settings related to the gamepad, all using the same n-key endpoint */
+ struct ally_gamepad_cfg {
+ struct hid_device *hdev;
+@@ -302,6 +324,9 @@ struct ally_gamepad_cfg {
+ /* joystick response curves */
+ struct response_curve ls_rc;
+ struct response_curve rs_rc;
++
++ struct js_axis_calibrations js_cal;
++ struct tr_axis_calibrations tr_cal;
+ };
+
+ /* The hatswitch outputs integers, we use them to index this X|Y pair */
+@@ -379,6 +404,18 @@ static struct ally_drvdata {
+ struct ally_rgb_data led_rgb_data;
+ } drvdata;
+
++static void reverse_bytes_in_pairs(u8 *buf, size_t size) {
++ uint16_t *word_ptr;
++ size_t i;
++
++ for (i = 0; i < size; i += 2) {
++ if (i + 1 < size) {
++ word_ptr = (uint16_t *)&buf[i];
++ *word_ptr = cpu_to_be16(*word_ptr);
++ }
++ }
++}
++
+ static int asus_dev_get_report(struct hid_device *hdev, u8 *out_buf, size_t out_buf_size)
+ {
+ return hid_hw_raw_request(hdev, FEATURE_REPORT_ID, out_buf, out_buf_size,
+@@ -792,6 +829,63 @@ ALLY_JS_RC_POINT(axis_xy_right, response, 2);
+ ALLY_JS_RC_POINT(axis_xy_right, response, 3);
+ ALLY_JS_RC_POINT(axis_xy_right, response, 4);
+
++/* CALIBRATIONS ***********************************************************************************/
++static int gamepad_get_calibration(struct hid_device *hdev)
++{
++ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
++ u8 *hidbuf;
++ int ret, i;
++
++ if (!drvdata.gamepad_cfg)
++ return -ENODEV;
++
++ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
++ if (!hidbuf)
++ return -ENOMEM;
++
++ for (i = 0; i < 2; i++) {
++ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
++ hidbuf[1] = 0xD0;
++ hidbuf[2] = 0x03;
++ hidbuf[3] = i + 1; // 0x01 JS, 0x02 TR
++ hidbuf[4] = 0x20;
++
++ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0) {
++ hid_warn(hdev, "ROG Ally check failed set report: %d\n", ret);
++ goto cleanup;
++ }
++
++ memset(hidbuf, 0, FEATURE_ROG_ALLY_REPORT_SIZE);
++ ret = asus_dev_get_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
++ if (ret < 0 || hidbuf[5] != 1) {
++ hid_warn(hdev, "ROG Ally check failed get report: %d\n", ret);
++ goto cleanup;
++ }
++
++ if (i == 0) {
++ /* Joystick calibration */
++ reverse_bytes_in_pairs(&hidbuf[6], sizeof(struct js_axis_calibrations));
++ ally_cfg->js_cal = *(struct js_axis_calibrations *)&hidbuf[6];
++ print_hex_dump(KERN_INFO, "HID Buffer JS: ", DUMP_PREFIX_OFFSET, 16, 1, hidbuf, 32, true);
++ struct js_axis_calibrations *cal = &drvdata.gamepad_cfg->js_cal;
++ pr_err("LS_CAL: X: %d, Min: %d, Max: %d", cal->left_x_stable, cal->left_x_min, cal->left_x_max);
++ pr_err("LS_CAL: Y: %d, Min: %d, Max: %d", cal->left_y_stable, cal->left_y_min, cal->left_y_max);
++ pr_err("RS_CAL: X: %d, Min: %d, Max: %d", cal->right_x_stable, cal->right_x_min, cal->right_x_max);
++ pr_err("RS_CAL: Y: %d, Min: %d, Max: %d", cal->right_y_stable, cal->right_y_min, cal->right_y_max);
++ } else {
++ /* Trigger calibration */
++ reverse_bytes_in_pairs(&hidbuf[6], sizeof(struct tr_axis_calibrations));
++ ally_cfg->tr_cal = *(struct tr_axis_calibrations *)&hidbuf[6];
++ print_hex_dump(KERN_INFO, "HID Buffer TR: ", DUMP_PREFIX_OFFSET, 16, 1, hidbuf, 32, true);
++ }
++ }
++
++cleanup:
++ kfree(hidbuf);
++ return ret;
++}
++
+ static struct attribute *axis_xy_left_attrs[] = {
+ &dev_attr_axis_xy_left_anti_deadzone.attr,
+ &dev_attr_axis_xy_left_deadzone.attr,
+@@ -1263,6 +1357,7 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
+ ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m1.button = BTN_KB_M1;
+ ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m2.button = BTN_KB_M2;
+ _gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_m1_m2);
++ gamepad_get_calibration(hdev);
+
+ ally_cfg->vibration_intensity[0] = 0x64;
+ ally_cfg->vibration_intensity[1] = 0x64;
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0026-debug-by-default.patch b/packages/l/linux-current/files/patches/hardware/asus/0026-debug-by-default.patch
new file mode 100644
index 00000000000..5f026178a82
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0026-debug-by-default.patch
@@ -0,0 +1,36 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Wed, 6 Nov 2024 00:27:03 +0300
+Subject: [PATCH 26/27] debug by default
+
+---
+ drivers/hid/hid-asus-ally.c | 2 ++
+ drivers/platform/x86/asus-armoury.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
+index 03603695c484..d2fbb08babdb 100644
+--- a/drivers/hid/hid-asus-ally.c
++++ b/drivers/hid/hid-asus-ally.c
+@@ -19,6 +19,8 @@
+ #include "hid-ids.h"
+ #include "hid-asus-ally.h"
+
++#define DEBUG
++
+ #define READY_MAX_TRIES 3
+ #define FEATURE_REPORT_ID 0x0d
+ #define FEATURE_ROG_ALLY_REPORT_ID 0x5a
+diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
+index 69e79446c411..fb4ae804521d 100644
+--- a/drivers/platform/x86/asus-armoury.c
++++ b/drivers/platform/x86/asus-armoury.c
+@@ -27,6 +27,8 @@
+ #include "asus-armoury.h"
+ #include "firmware_attributes_class.h"
+
++#define DEBUG
++
+ #define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C"
+
+ #define ASUS_MINI_LED_MODE_MASK 0x03
diff --git a/packages/l/linux-current/files/patches/hardware/asus/0027-Tmp-add-GA605W-H7606W-to-AMD-PMF-quirks.patch b/packages/l/linux-current/files/patches/hardware/asus/0027-Tmp-add-GA605W-H7606W-to-AMD-PMF-quirks.patch
new file mode 100644
index 00000000000..78896a03302
--- /dev/null
+++ b/packages/l/linux-current/files/patches/hardware/asus/0027-Tmp-add-GA605W-H7606W-to-AMD-PMF-quirks.patch
@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones"
+Date: Tue, 17 Dec 2024 09:31:08 +1300
+Subject: [PATCH 27/27] Tmp: add GA605W & H7606W to AMD-PMF quirks.
+
+This will not be submitted upstream as the entire
+quirk system is being removed in 6.14 kernel.
+
+Signed-off-by: Luke D. Jones
+---
+ drivers/platform/x86/amd/pmf/pmf-quirks.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/platform/x86/amd/pmf/pmf-quirks.c b/drivers/platform/x86/amd/pmf/pmf-quirks.c
+index 7cde5733b9ca..02b9d0b49092 100644
+--- a/drivers/platform/x86/amd/pmf/pmf-quirks.c
++++ b/drivers/platform/x86/amd/pmf/pmf-quirks.c
+@@ -29,6 +29,22 @@ static const struct dmi_system_id fwbug_list[] = {
+ },
+ .driver_data = &quirk_no_sps_bug,
+ },
++ {
++ .ident = "ROG Zephyrus G16",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "GA605W"),
++ },
++ .driver_data = &quirk_no_sps_bug,
++ },
++ {
++ .ident = "ProArt P16",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "H7606W"),
++ },
++ .driver_data = &quirk_no_sps_bug,
++ },
+ {
+ .ident = "ROG Ally X",
+ .matches = {
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0001-Revert-efi-x86-Set-the-PE-COFF-header-s-NX-compat-fl.patch b/packages/l/linux-current/files/patches/hardware/surface/0001-Revert-efi-x86-Set-the-PE-COFF-header-s-NX-compat-fl.patch
index 97fb0ccbe99..e403c356bb7 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0001-Revert-efi-x86-Set-the-PE-COFF-header-s-NX-compat-fl.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0001-Revert-efi-x86-Set-the-PE-COFF-header-s-NX-compat-fl.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Sun, 9 Jun 2024 19:48:58 +0200
-Subject: [PATCH 01/37] Revert "efi/x86: Set the PE/COFF header's NX compat
+Subject: [PATCH 01/34] Revert "efi/x86: Set the PE/COFF header's NX compat
flag unconditionally"
This reverts commit 891f8890a4a3663da7056542757022870b499bc1.
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0002-PM-hibernate-Add-a-lockdown_hibernate-parameter.patch b/packages/l/linux-current/files/patches/hardware/surface/0002-PM-hibernate-Add-a-lockdown_hibernate-parameter.patch
index f51c355b3f0..f32708310cf 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0002-PM-hibernate-Add-a-lockdown_hibernate-parameter.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0002-PM-hibernate-Add-a-lockdown_hibernate-parameter.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "J. Eduardo"
Date: Sun, 25 Aug 2024 14:17:45 +0200
-Subject: [PATCH 02/37] PM: hibernate: Add a lockdown_hibernate parameter
+Subject: [PATCH 02/34] PM: hibernate: Add a lockdown_hibernate parameter
This allows the user to tell the kernel that they know better (namely,
they secured their swap properly), and that it can enable hibernation.
@@ -16,10 +16,10 @@ Patchset: secureboot
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
-index 09126bb8cc9f..d4203d40146e 100644
+index d401577b5a6a..5a812e0b740a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
-@@ -3020,6 +3020,11 @@
+@@ -3066,6 +3066,11 @@
to extract confidential information from the kernel
are also disabled.
@@ -32,7 +32,7 @@ index 09126bb8cc9f..d4203d40146e 100644
Set the time limit in jiffies for a lock
acquisition. Acquisitions exceeding this limit
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
-index 0a213f69a9e4..8e4f9dcc9f4c 100644
+index e35829d36039..6d54eb03b63d 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -37,6 +37,7 @@
@@ -52,7 +52,7 @@ index 0a213f69a9e4..8e4f9dcc9f4c 100644
!secretmem_active() && !cxl_mem_active();
}
-@@ -1422,6 +1423,12 @@ static int __init nohibernate_setup(char *str)
+@@ -1426,6 +1427,12 @@ static int __init nohibernate_setup(char *str)
return 1;
}
@@ -65,7 +65,7 @@ index 0a213f69a9e4..8e4f9dcc9f4c 100644
static const char * const comp_alg_enabled[] = {
#if IS_ENABLED(CONFIG_CRYPTO_LZO)
COMPRESSION_ALGO_LZO,
-@@ -1480,3 +1487,4 @@ __setup("hibernate=", hibernate_setup);
+@@ -1484,3 +1491,4 @@ __setup("hibernate=", hibernate_setup);
__setup("resumewait", resumewait_setup);
__setup("resumedelay=", resumedelay_setup);
__setup("nohibernate", nohibernate_setup);
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0003-surface3-oemb-add-DMI-matches-for-Surface-3-with-bro.patch b/packages/l/linux-current/files/patches/hardware/surface/0003-surface3-oemb-add-DMI-matches-for-Surface-3-with-bro.patch
index bd43dcb8575..e440f6fdcff 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0003-surface3-oemb-add-DMI-matches-for-Surface-3-with-bro.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0003-surface3-oemb-add-DMI-matches-for-Surface-3-with-bro.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tsuchiya Yuto
Date: Sun, 18 Oct 2020 16:42:44 +0900
-Subject: [PATCH 03/37] (surface3-oemb) add DMI matches for Surface 3 with
+Subject: [PATCH 03/34] (surface3-oemb) add DMI matches for Surface 3 with
broken DMI table
On some Surface 3, the DMI table gets corrupted for unknown reasons
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0004-mwifiex-Add-quirk-resetting-the-PCI-bridge-on-MS-Sur.patch b/packages/l/linux-current/files/patches/hardware/surface/0004-mwifiex-Add-quirk-resetting-the-PCI-bridge-on-MS-Sur.patch
index c073ed92373..f989f668ad3 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0004-mwifiex-Add-quirk-resetting-the-PCI-bridge-on-MS-Sur.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0004-mwifiex-Add-quirk-resetting-the-PCI-bridge-on-MS-Sur.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?=
Date: Tue, 3 Nov 2020 13:28:04 +0100
-Subject: [PATCH 04/37] mwifiex: Add quirk resetting the PCI bridge on MS
+Subject: [PATCH 04/34] mwifiex: Add quirk resetting the PCI bridge on MS
Surface devices
The most recent firmware of the 88W8897 card reports a hardcoded LTR
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0005-mwifiex-pcie-disable-bridge_d3-for-Surface-gen4.patch b/packages/l/linux-current/files/patches/hardware/surface/0005-mwifiex-pcie-disable-bridge_d3-for-Surface-gen4.patch
index c70fa0ffe47..5f8ff001a1c 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0005-mwifiex-pcie-disable-bridge_d3-for-Surface-gen4.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0005-mwifiex-pcie-disable-bridge_d3-for-Surface-gen4.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tsuchiya Yuto
Date: Sun, 4 Oct 2020 00:11:49 +0900
-Subject: [PATCH 05/37] mwifiex: pcie: disable bridge_d3 for Surface gen4+
+Subject: [PATCH 05/34] mwifiex: pcie: disable bridge_d3 for Surface gen4+
Currently, mwifiex fw will crash after suspend on recent kernel series.
On Windows, it seems that the root port of wifi will never enter D3 state
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0006-Bluetooth-btusb-Lower-passive-lescan-interval-on-Mar.patch b/packages/l/linux-current/files/patches/hardware/surface/0006-Bluetooth-btusb-Lower-passive-lescan-interval-on-Mar.patch
index 27ddb16799c..b80adcce5ea 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0006-Bluetooth-btusb-Lower-passive-lescan-interval-on-Mar.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0006-Bluetooth-btusb-Lower-passive-lescan-interval-on-Mar.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?=
Date: Thu, 25 Mar 2021 11:33:02 +0100
-Subject: [PATCH 06/37] Bluetooth: btusb: Lower passive lescan interval on
+Subject: [PATCH 06/34] Bluetooth: btusb: Lower passive lescan interval on
Marvell 88W8897
The Marvell 88W8897 combined wifi and bluetooth card (pcie+usb version)
@@ -34,7 +34,7 @@ Patchset: mwifiex
1 file changed, 15 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
-index 1ec71a2fb63e..b438707e48e6 100644
+index 11755cb1eb16..e69c6c9957a2 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -65,6 +65,7 @@ static struct usb_driver btusb_driver;
@@ -45,7 +45,7 @@ index 1ec71a2fb63e..b438707e48e6 100644
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
-@@ -468,6 +469,7 @@ static const struct usb_device_id quirks_table[] = {
+@@ -432,6 +433,7 @@ static const struct usb_device_id quirks_table[] = {
{ USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
{ USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
{ USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL },
@@ -53,7 +53,7 @@ index 1ec71a2fb63e..b438707e48e6 100644
/* Intel Bluetooth devices */
{ USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_COMBINED },
-@@ -3859,6 +3861,19 @@ static int btusb_probe(struct usb_interface *intf,
+@@ -3837,6 +3839,19 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_MARVELL)
hdev->set_bdaddr = btusb_set_bdaddr_marvell;
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0007-ath10k-Add-module-parameters-to-override-board-files.patch b/packages/l/linux-current/files/patches/hardware/surface/0007-ath10k-Add-module-parameters-to-override-board-files.patch
index 51353dc2af0..e0186e10d7b 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0007-ath10k-Add-module-parameters-to-override-board-files.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0007-ath10k-Add-module-parameters-to-override-board-files.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Sat, 27 Feb 2021 00:45:52 +0100
-Subject: [PATCH 07/37] ath10k: Add module parameters to override board files
+Subject: [PATCH 07/34] ath10k: Add module parameters to override board files
Some Surface devices, specifically the Surface Go and AMD version of the
Surface Laptop 3 (wich both come with QCA6174 WiFi chips), work better
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0008-mei-me-Add-Icelake-device-ID-for-iTouch.patch b/packages/l/linux-current/files/patches/hardware/surface/0008-mei-me-Add-Icelake-device-ID-for-iTouch.patch
index d2297f04b0c..ef9d50fe854 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0008-mei-me-Add-Icelake-device-ID-for-iTouch.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0008-mei-me-Add-Icelake-device-ID-for-iTouch.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dorian Stoll
Date: Thu, 30 Jul 2020 13:21:53 +0200
-Subject: [PATCH 08/37] mei: me: Add Icelake device ID for iTouch
+Subject: [PATCH 08/34] mei: me: Add Icelake device ID for iTouch
Signed-off-by: Dorian Stoll
Patchset: ipts
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0009-iommu-Use-IOMMU-passthrough-mode-for-IPTS.patch b/packages/l/linux-current/files/patches/hardware/surface/0009-iommu-Use-IOMMU-passthrough-mode-for-IPTS.patch
index cb9ca971944..0f6dc535a34 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0009-iommu-Use-IOMMU-passthrough-mode-for-IPTS.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0009-iommu-Use-IOMMU-passthrough-mode-for-IPTS.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Liban Hannan
Date: Tue, 12 Apr 2022 23:31:12 +0100
-Subject: [PATCH 09/37] iommu: Use IOMMU passthrough mode for IPTS
+Subject: [PATCH 09/34] iommu: Use IOMMU passthrough mode for IPTS
Adds a quirk so that IOMMU uses passthrough mode for the IPTS device.
Otherwise, when IOMMU is enabled, IPTS produces DMAR errors like:
@@ -22,7 +22,7 @@ Patchset: ipts
1 file changed, 29 insertions(+)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
-index 4aa070cf56e7..5df658b9811b 100644
+index a167d59101ae..f18d5635d2f6 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -40,6 +40,11 @@
@@ -37,7 +37,7 @@ index 4aa070cf56e7..5df658b9811b 100644
#define IOAPIC_RANGE_START (0xfee00000)
#define IOAPIC_RANGE_END (0xfeefffff)
#define IOVA_START_ADDR (0x1000)
-@@ -217,12 +222,14 @@ int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
+@@ -208,12 +213,14 @@ int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
int intel_iommu_enabled = 0;
EXPORT_SYMBOL_GPL(intel_iommu_enabled);
@@ -52,7 +52,7 @@ index 4aa070cf56e7..5df658b9811b 100644
const struct iommu_ops intel_iommu_ops;
static const struct iommu_dirty_ops intel_dirty_ops;
-@@ -2156,6 +2163,9 @@ static int device_def_domain_type(struct device *dev)
+@@ -2046,6 +2053,9 @@ static int device_def_domain_type(struct device *dev)
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
return IOMMU_DOMAIN_IDENTITY;
@@ -62,7 +62,7 @@ index 4aa070cf56e7..5df658b9811b 100644
}
return 0;
-@@ -2456,6 +2466,9 @@ static int __init init_dmars(void)
+@@ -2344,6 +2354,9 @@ static int __init init_dmars(void)
iommu_set_root_entry(iommu);
}
@@ -71,8 +71,8 @@ index 4aa070cf56e7..5df658b9811b 100644
+
check_tylersburg_isoch();
- ret = si_domain_init(hw_pass_through);
-@@ -4699,6 +4712,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev)
+ /*
+@@ -4649,6 +4662,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev)
disable_igfx_iommu = 1;
}
@@ -91,7 +91,7 @@ index 4aa070cf56e7..5df658b9811b 100644
/* G4x/GM45 integrated gfx dmar support is totally busted. */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
-@@ -4734,6 +4759,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
+@@ -4684,6 +4709,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0010-hid-Add-support-for-Intel-Precise-Touch-and-Stylus.patch b/packages/l/linux-current/files/patches/hardware/surface/0010-hid-Add-support-for-Intel-Precise-Touch-and-Stylus.patch
index 0ddbdf9ebce..57ccec7449d 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0010-hid-Add-support-for-Intel-Precise-Touch-and-Stylus.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0010-hid-Add-support-for-Intel-Precise-Touch-and-Stylus.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dorian Stoll
Date: Sun, 11 Dec 2022 12:00:59 +0100
-Subject: [PATCH 10/37] hid: Add support for Intel Precise Touch and Stylus
+Subject: [PATCH 10/34] hid: Add support for Intel Precise Touch and Stylus
Based on linux-surface/intel-precise-touch@8abe268
@@ -65,10 +65,10 @@ Patchset: ipts
create mode 100644 drivers/hid/ipts/thread.h
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
-index 08446c89eff6..ccddfba86004 100644
+index d477df3a3f35..32cd9288d22b 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
-@@ -1367,4 +1367,6 @@ source "drivers/hid/amd-sfh-hid/Kconfig"
+@@ -1382,4 +1382,6 @@ source "drivers/hid/amd-sfh-hid/Kconfig"
source "drivers/hid/surface-hid/Kconfig"
@@ -76,10 +76,10 @@ index 08446c89eff6..ccddfba86004 100644
+
endif # HID_SUPPORT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
-index e40f1ddebbb7..bdb17cffca2f 100644
+index 5fa65e1e1e3b..1b4e134bb137 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
-@@ -169,3 +169,5 @@ obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ish-hid/
+@@ -171,3 +171,5 @@ obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ish-hid/
obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/
obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0011-iommu-intel-Disable-source-id-verification-for-ITHC.patch b/packages/l/linux-current/files/patches/hardware/surface/0011-iommu-intel-Disable-source-id-verification-for-ITHC.patch
index 7084baa75bc..8819ecf5e9a 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0011-iommu-intel-Disable-source-id-verification-for-ITHC.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0011-iommu-intel-Disable-source-id-verification-for-ITHC.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dorian Stoll
Date: Sun, 11 Dec 2022 12:03:38 +0100
-Subject: [PATCH 11/37] iommu: intel: Disable source id verification for ITHC
+Subject: [PATCH 11/34] iommu: intel: Disable source id verification for ITHC
Signed-off-by: Dorian Stoll
Patchset: ithc
@@ -10,7 +10,7 @@ Patchset: ithc
1 file changed, 16 insertions(+)
diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c
-index e090ca07364b..e575193615bf 100644
+index 7a6d188e3bea..0179baee4596 100644
--- a/drivers/iommu/intel/irq_remapping.c
+++ b/drivers/iommu/intel/irq_remapping.c
@@ -389,6 +389,22 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev)
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0012-hid-Add-support-for-Intel-Touch-Host-Controller.patch b/packages/l/linux-current/files/patches/hardware/surface/0012-hid-Add-support-for-Intel-Touch-Host-Controller.patch
index 4c9def3c958..bb8790af224 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0012-hid-Add-support-for-Intel-Touch-Host-Controller.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0012-hid-Add-support-for-Intel-Touch-Host-Controller.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: quo
Date: Sun, 11 Dec 2022 12:10:54 +0100
-Subject: [PATCH 12/37] hid: Add support for Intel Touch Host Controller
+Subject: [PATCH 12/34] hid: Add support for Intel Touch Host Controller
Based on quo/ithc-linux@34539af4726d.
@@ -45,10 +45,10 @@ Patchset: ithc
create mode 100644 drivers/hid/ithc/ithc.h
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
-index ccddfba86004..8e2ea8175bfb 100644
+index 32cd9288d22b..b38f49322f8a 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
-@@ -1369,4 +1369,6 @@ source "drivers/hid/surface-hid/Kconfig"
+@@ -1384,4 +1384,6 @@ source "drivers/hid/surface-hid/Kconfig"
source "drivers/hid/ipts/Kconfig"
@@ -56,10 +56,10 @@ index ccddfba86004..8e2ea8175bfb 100644
+
endif # HID_SUPPORT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
-index bdb17cffca2f..8987177f8b81 100644
+index 1b4e134bb137..854ad11f663f 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
-@@ -171,3 +171,4 @@ obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/
+@@ -173,3 +173,4 @@ obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/
obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/
obj-$(CONFIG_HID_IPTS) += ipts/
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0013-hwmon-Add-thermal-sensor-driver-for-Surface-Aggregat.patch b/packages/l/linux-current/files/patches/hardware/surface/0013-hwmon-Add-thermal-sensor-driver-for-Surface-Aggregat.patch
deleted file mode 100644
index 8fb7f138a0f..00000000000
--- a/packages/l/linux-current/files/patches/hardware/surface/0013-hwmon-Add-thermal-sensor-driver-for-Surface-Aggregat.patch
+++ /dev/null
@@ -1,225 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maximilian Luz
-Date: Sat, 30 Dec 2023 18:07:54 +0100
-Subject: [PATCH 13/37] hwmon: Add thermal sensor driver for Surface Aggregator
- Module
-
-Some of the newer Microsoft Surface devices (such as the Surface Book
-3 and Pro 9) have thermal sensors connected via the Surface Aggregator
-Module (the embedded controller on those devices). Add a basic driver
-to read out the temperature values of those sensors.
-
-Link: https://github.com/linux-surface/surface-aggregator-module/issues/59
-Signed-off-by: Maximilian Luz
-Patchset: surface-sam
----
- drivers/hwmon/Kconfig | 10 +++
- drivers/hwmon/Makefile | 1 +
- drivers/hwmon/surface_temp.c | 165 +++++++++++++++++++++++++++++++++++
- 3 files changed, 176 insertions(+)
- create mode 100644 drivers/hwmon/surface_temp.c
-
-diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
-index b60fe2e58ad6..70c6385f0ed6 100644
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -2080,6 +2080,16 @@ config SENSORS_SURFACE_FAN
-
- Select M or Y here, if you want to be able to read the fan's speed.
-
-+config SENSORS_SURFACE_TEMP
-+ tristate "Microsoft Surface Thermal Sensor Driver"
-+ depends on SURFACE_AGGREGATOR
-+ help
-+ Driver for monitoring thermal sensors connected via the Surface
-+ Aggregator Module (embedded controller) on Microsoft Surface devices.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called surface_temp.
-+
- config SENSORS_ADC128D818
- tristate "Texas Instruments ADC128D818"
- depends on I2C
-diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
-index b1c7056c37db..3ce8d6a9202e 100644
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -209,6 +209,7 @@ obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o
- obj-$(CONFIG_SENSORS_SPD5118) += spd5118.o
- obj-$(CONFIG_SENSORS_STTS751) += stts751.o
- obj-$(CONFIG_SENSORS_SURFACE_FAN)+= surface_fan.o
-+obj-$(CONFIG_SENSORS_SURFACE_TEMP)+= surface_temp.o
- obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o
- obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
- obj-$(CONFIG_SENSORS_TC74) += tc74.o
-diff --git a/drivers/hwmon/surface_temp.c b/drivers/hwmon/surface_temp.c
-new file mode 100644
-index 000000000000..48c3e826713f
---- /dev/null
-+++ b/drivers/hwmon/surface_temp.c
-@@ -0,0 +1,165 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Thermal sensor subsystem driver for Surface System Aggregator Module (SSAM).
-+ *
-+ * Copyright (C) 2022-2023 Maximilian Luz
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include
-+#include
-+
-+
-+/* -- SAM interface. -------------------------------------------------------- */
-+
-+SSAM_DEFINE_SYNC_REQUEST_CL_R(__ssam_tmp_get_available_sensors, __le16, {
-+ .target_category = SSAM_SSH_TC_TMP,
-+ .command_id = 0x04,
-+});
-+
-+SSAM_DEFINE_SYNC_REQUEST_MD_R(__ssam_tmp_get_temperature, __le16, {
-+ .target_category = SSAM_SSH_TC_TMP,
-+ .command_id = 0x01,
-+});
-+
-+static int ssam_tmp_get_available_sensors(struct ssam_device *sdev, s16 *sensors)
-+{
-+ __le16 sensors_le;
-+ int status;
-+
-+ status = __ssam_tmp_get_available_sensors(sdev, &sensors_le);
-+ if (status)
-+ return status;
-+
-+ *sensors = le16_to_cpu(sensors_le);
-+ return 0;
-+}
-+
-+static int ssam_tmp_get_temperature(struct ssam_device *sdev, u8 iid, long *temperature)
-+{
-+ __le16 temp_le;
-+ int status;
-+
-+ status = __ssam_tmp_get_temperature(sdev->ctrl, sdev->uid.target, iid, &temp_le);
-+ if (status)
-+ return status;
-+
-+ /* Convert 1/10 °K to 1/1000 °C */
-+ *temperature = (le16_to_cpu(temp_le) - 2731) * 100L;
-+ return 0;
-+}
-+
-+
-+/* -- Driver.---------------------------------------------------------------- */
-+
-+struct ssam_temp {
-+ struct ssam_device *sdev;
-+ s16 sensors;
-+};
-+
-+static umode_t ssam_temp_hwmon_is_visible(const void *data,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel)
-+{
-+ const struct ssam_temp *ssam_temp = data;
-+
-+ if (!(ssam_temp->sensors & BIT(channel)))
-+ return 0;
-+
-+ return 0444;
-+}
-+
-+static int ssam_temp_hwmon_read(struct device *dev,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *value)
-+{
-+ const struct ssam_temp *ssam_temp = dev_get_drvdata(dev);
-+
-+ return ssam_tmp_get_temperature(ssam_temp->sdev, channel + 1, value);
-+}
-+
-+static const struct hwmon_channel_info * const ssam_temp_hwmon_info[] = {
-+ HWMON_CHANNEL_INFO(chip,
-+ HWMON_C_REGISTER_TZ),
-+ /* We have at most 16 thermal sensor channels. */
-+ HWMON_CHANNEL_INFO(temp,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT),
-+ NULL
-+};
-+
-+static const struct hwmon_ops ssam_temp_hwmon_ops = {
-+ .is_visible = ssam_temp_hwmon_is_visible,
-+ .read = ssam_temp_hwmon_read,
-+};
-+
-+static const struct hwmon_chip_info ssam_temp_hwmon_chip_info = {
-+ .ops = &ssam_temp_hwmon_ops,
-+ .info = ssam_temp_hwmon_info,
-+};
-+
-+static int ssam_temp_probe(struct ssam_device *sdev)
-+{
-+ struct ssam_temp *ssam_temp;
-+ struct device *hwmon_dev;
-+ s16 sensors;
-+ int status;
-+
-+ status = ssam_tmp_get_available_sensors(sdev, &sensors);
-+ if (status)
-+ return status;
-+
-+ ssam_temp = devm_kzalloc(&sdev->dev, sizeof(*ssam_temp), GFP_KERNEL);
-+ if (!ssam_temp)
-+ return -ENOMEM;
-+
-+ ssam_temp->sdev = sdev;
-+ ssam_temp->sensors = sensors;
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(&sdev->dev,
-+ "surface_thermal", ssam_temp, &ssam_temp_hwmon_chip_info,
-+ NULL);
-+ if (IS_ERR(hwmon_dev))
-+ return PTR_ERR(hwmon_dev);
-+
-+ return 0;
-+}
-+
-+static const struct ssam_device_id ssam_temp_match[] = {
-+ { SSAM_SDEV(TMP, SAM, 0x00, 0x02) },
-+ { },
-+};
-+MODULE_DEVICE_TABLE(ssam, ssam_temp_match);
-+
-+static struct ssam_device_driver ssam_temp = {
-+ .probe = ssam_temp_probe,
-+ .match_table = ssam_temp_match,
-+ .driver = {
-+ .name = "surface_temp",
-+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-+ },
-+};
-+module_ssam_device_driver(ssam_temp);
-+
-+MODULE_AUTHOR("Maximilian Luz ");
-+MODULE_DESCRIPTION("Thermal sensor subsystem driver for Surface System Aggregator Module");
-+MODULE_LICENSE("GPL");
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0015-i2c-acpi-Implement-RawBytes-read-access.patch b/packages/l/linux-current/files/patches/hardware/surface/0013-i2c-acpi-Implement-RawBytes-read-access.patch
similarity index 98%
rename from packages/l/linux-current/files/patches/hardware/surface/0015-i2c-acpi-Implement-RawBytes-read-access.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0013-i2c-acpi-Implement-RawBytes-read-access.patch
index df2b6858a63..76cc51460dd 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0015-i2c-acpi-Implement-RawBytes-read-access.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0013-i2c-acpi-Implement-RawBytes-read-access.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Sat, 25 Jul 2020 17:19:53 +0200
-Subject: [PATCH 15/37] i2c: acpi: Implement RawBytes read access
+Subject: [PATCH 13/34] i2c: acpi: Implement RawBytes read access
Microsoft Surface Pro 4 and Book 1 devices access the MSHW0030 I2C
device via a generic serial bus operation region and RawBytes read
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0014-hwmon-surface_temp-Add-support-for-sensor-names.patch b/packages/l/linux-current/files/patches/hardware/surface/0014-hwmon-surface_temp-Add-support-for-sensor-names.patch
deleted file mode 100644
index 40c4f46b96c..00000000000
--- a/packages/l/linux-current/files/patches/hardware/surface/0014-hwmon-surface_temp-Add-support-for-sensor-names.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Maximilian Luz
-Date: Sat, 30 Dec 2023 18:12:23 +0100
-Subject: [PATCH 14/37] hwmon: surface_temp: Add support for sensor names
-
-The thermal subsystem of the Surface Aggregator Module allows us to
-query the names of the respective thermal sensors. Forward those to
-userspace.
-
-Signed-off-by: Ivor Wanders
-Co-Developed-by: Maximilian Luz
-Signed-off-by: Maximilian Luz
-Patchset: surface-sam
----
- drivers/hwmon/surface_temp.c | 113 +++++++++++++++++++++++++++++------
- 1 file changed, 96 insertions(+), 17 deletions(-)
-
-diff --git a/drivers/hwmon/surface_temp.c b/drivers/hwmon/surface_temp.c
-index 48c3e826713f..4c08926139db 100644
---- a/drivers/hwmon/surface_temp.c
-+++ b/drivers/hwmon/surface_temp.c
-@@ -17,6 +17,27 @@
-
- /* -- SAM interface. -------------------------------------------------------- */
-
-+/*
-+ * Available sensors are indicated by a 16-bit bitfield, where a 1 marks the
-+ * presence of a sensor. So we have at most 16 possible sensors/channels.
-+ */
-+#define SSAM_TMP_SENSOR_MAX_COUNT 16
-+
-+/*
-+ * All names observed so far are 6 characters long, but there's only
-+ * zeros after the name, so perhaps they can be longer. This number reflects
-+ * the maximum zero-padded space observed in the returned buffer.
-+ */
-+#define SSAM_TMP_SENSOR_NAME_LENGTH 18
-+
-+struct ssam_tmp_get_name_rsp {
-+ __le16 unknown1;
-+ char unknown2;
-+ char name[SSAM_TMP_SENSOR_NAME_LENGTH];
-+} __packed;
-+
-+static_assert(sizeof(struct ssam_tmp_get_name_rsp) == 21);
-+
- SSAM_DEFINE_SYNC_REQUEST_CL_R(__ssam_tmp_get_available_sensors, __le16, {
- .target_category = SSAM_SSH_TC_TMP,
- .command_id = 0x04,
-@@ -27,6 +48,11 @@ SSAM_DEFINE_SYNC_REQUEST_MD_R(__ssam_tmp_get_temperature, __le16, {
- .command_id = 0x01,
- });
-
-+SSAM_DEFINE_SYNC_REQUEST_MD_R(__ssam_tmp_get_name, struct ssam_tmp_get_name_rsp, {
-+ .target_category = SSAM_SSH_TC_TMP,
-+ .command_id = 0x0e,
-+});
-+
- static int ssam_tmp_get_available_sensors(struct ssam_device *sdev, s16 *sensors)
- {
- __le16 sensors_le;
-@@ -54,12 +80,37 @@ static int ssam_tmp_get_temperature(struct ssam_device *sdev, u8 iid, long *temp
- return 0;
- }
-
-+static int ssam_tmp_get_name(struct ssam_device *sdev, u8 iid, char *buf, size_t buf_len)
-+{
-+ struct ssam_tmp_get_name_rsp name_rsp;
-+ int status;
-+
-+ status = __ssam_tmp_get_name(sdev->ctrl, sdev->uid.target, iid, &name_rsp);
-+ if (status)
-+ return status;
-+
-+ /*
-+ * This should not fail unless the name in the returned struct is not
-+ * null-terminated or someone changed something in the struct
-+ * definitions above, since our buffer and struct have the same
-+ * capacity by design. So if this fails blow this up with a warning.
-+ * Since the more likely cause is that the returned string isn't
-+ * null-terminated, we might have received garbage (as opposed to just
-+ * an incomplete string), so also fail the function.
-+ */
-+ status = strscpy(buf, name_rsp.name, buf_len);
-+ WARN_ON(status < 0);
-+
-+ return status < 0 ? status : 0;
-+}
-+
-
- /* -- Driver.---------------------------------------------------------------- */
-
- struct ssam_temp {
- struct ssam_device *sdev;
- s16 sensors;
-+ char names[SSAM_TMP_SENSOR_MAX_COUNT][SSAM_TMP_SENSOR_NAME_LENGTH];
- };
-
- static umode_t ssam_temp_hwmon_is_visible(const void *data,
-@@ -83,33 +134,47 @@ static int ssam_temp_hwmon_read(struct device *dev,
- return ssam_tmp_get_temperature(ssam_temp->sdev, channel + 1, value);
- }
-
-+static int ssam_temp_hwmon_read_string(struct device *dev,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel, const char **str)
-+{
-+ const struct ssam_temp *ssam_temp = dev_get_drvdata(dev);
-+
-+ *str = ssam_temp->names[channel];
-+ return 0;
-+}
-+
- static const struct hwmon_channel_info * const ssam_temp_hwmon_info[] = {
- HWMON_CHANNEL_INFO(chip,
- HWMON_C_REGISTER_TZ),
-- /* We have at most 16 thermal sensor channels. */
-+ /*
-+ * We have at most SSAM_TMP_SENSOR_MAX_COUNT = 16 thermal sensor
-+ * channels.
-+ */
- HWMON_CHANNEL_INFO(temp,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT,
-- HWMON_T_INPUT),
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL,
-+ HWMON_T_INPUT | HWMON_T_LABEL),
- NULL
- };
-
- static const struct hwmon_ops ssam_temp_hwmon_ops = {
- .is_visible = ssam_temp_hwmon_is_visible,
- .read = ssam_temp_hwmon_read,
-+ .read_string = ssam_temp_hwmon_read_string,
- };
-
- static const struct hwmon_chip_info ssam_temp_hwmon_chip_info = {
-@@ -122,6 +187,7 @@ static int ssam_temp_probe(struct ssam_device *sdev)
- struct ssam_temp *ssam_temp;
- struct device *hwmon_dev;
- s16 sensors;
-+ int channel;
- int status;
-
- status = ssam_tmp_get_available_sensors(sdev, &sensors);
-@@ -135,6 +201,19 @@ static int ssam_temp_probe(struct ssam_device *sdev)
- ssam_temp->sdev = sdev;
- ssam_temp->sensors = sensors;
-
-+ /* Retrieve the name for each available sensor. */
-+ for (channel = 0; channel < SSAM_TMP_SENSOR_MAX_COUNT; channel++)
-+ {
-+ if (!(sensors & BIT(channel)))
-+ continue;
-+
-+ status = ssam_tmp_get_name(sdev, channel + 1,
-+ ssam_temp->names[channel],
-+ SSAM_TMP_SENSOR_NAME_LENGTH);
-+ if (status)
-+ return status;
-+ }
-+
- hwmon_dev = devm_hwmon_device_register_with_info(&sdev->dev,
- "surface_thermal", ssam_temp, &ssam_temp_hwmon_chip_info,
- NULL);
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0016-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch b/packages/l/linux-current/files/patches/hardware/surface/0014-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch
similarity index 98%
rename from packages/l/linux-current/files/patches/hardware/surface/0016-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0014-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch
index ae0b805f59d..beaa7c0d0cc 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0016-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0014-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Sat, 13 Feb 2021 16:41:18 +0100
-Subject: [PATCH 16/37] platform/surface: Add driver for Surface Book 1 dGPU
+Subject: [PATCH 14/34] platform/surface: Add driver for Surface Book 1 dGPU
switch
Add driver exposing the discrete GPU power-switch of the Microsoft
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0017-Input-soc_button_array-support-AMD-variant-Surface-d.patch b/packages/l/linux-current/files/patches/hardware/surface/0015-Input-soc_button_array-support-AMD-variant-Surface-d.patch
similarity index 97%
rename from packages/l/linux-current/files/patches/hardware/surface/0017-Input-soc_button_array-support-AMD-variant-Surface-d.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0015-Input-soc_button_array-support-AMD-variant-Surface-d.patch
index 8a00610076c..00749125c12 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0017-Input-soc_button_array-support-AMD-variant-Surface-d.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0015-Input-soc_button_array-support-AMD-variant-Surface-d.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sachi King
Date: Tue, 5 Oct 2021 00:05:09 +1100
-Subject: [PATCH 17/37] Input: soc_button_array - support AMD variant Surface
+Subject: [PATCH 15/34] Input: soc_button_array - support AMD variant Surface
devices
The power button on the AMD variant of the Surface Laptop uses the
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0018-platform-surface-surfacepro3_button-don-t-load-on-am.patch b/packages/l/linux-current/files/patches/hardware/surface/0016-platform-surface-surfacepro3_button-don-t-load-on-am.patch
similarity index 97%
rename from packages/l/linux-current/files/patches/hardware/surface/0018-platform-surface-surfacepro3_button-don-t-load-on-am.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0016-platform-surface-surfacepro3_button-don-t-load-on-am.patch
index b9b28626fe5..045df0d31e0 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0018-platform-surface-surfacepro3_button-don-t-load-on-am.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0016-platform-surface-surfacepro3_button-don-t-load-on-am.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sachi King
Date: Tue, 5 Oct 2021 00:22:57 +1100
-Subject: [PATCH 18/37] platform/surface: surfacepro3_button: don't load on amd
+Subject: [PATCH 16/34] platform/surface: surfacepro3_button: don't load on amd
variant
The AMD variant of the Surface Laptop report 0 for their OEM platform
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0019-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch b/packages/l/linux-current/files/patches/hardware/surface/0017-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch
similarity index 96%
rename from packages/l/linux-current/files/patches/hardware/surface/0019-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0017-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch
index 6f27e7535df..13dda949f06 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0019-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0017-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Sat, 18 Feb 2023 01:02:49 +0100
-Subject: [PATCH 19/37] USB: quirks: Add USB_QUIRK_DELAY_INIT for Surface Go 3
+Subject: [PATCH 17/34] USB: quirks: Add USB_QUIRK_DELAY_INIT for Surface Go 3
Type-Cover
The touchpad on the Type-Cover of the Surface Go 3 is sometimes not
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0020-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch b/packages/l/linux-current/files/patches/hardware/surface/0018-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch
similarity index 89%
rename from packages/l/linux-current/files/patches/hardware/surface/0020-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0018-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch
index e576ba12088..a5f854f7b70 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0020-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0018-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?=
Date: Thu, 5 Nov 2020 13:09:45 +0100
-Subject: [PATCH 20/37] hid/multitouch: Turn off Type Cover keyboard backlight
+Subject: [PATCH 18/34] hid/multitouch: Turn off Type Cover keyboard backlight
when suspending
The Type Cover for Microsoft Surface devices supports a special usb
@@ -34,7 +34,7 @@ Patchset: surface-typecover
1 file changed, 98 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
-index 99812c0f830b..0b3b51e37149 100644
+index e936019d21fe..08fee06fb5fc 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -34,7 +34,10 @@
@@ -86,12 +86,12 @@ index 99812c0f830b..0b3b51e37149 100644
#define MT_CLS_RAZER_BLADE_STEALTH 0x0112
#define MT_CLS_SMART_TECH 0x0113
+#define MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER 0x0114
+ #define MT_CLS_SIS 0x0457
#define MT_DEFAULT_MAXCONTACT 10
- #define MT_MAX_MAXCONTACT 250
-@@ -396,6 +406,16 @@ static const struct mt_class mt_classes[] = {
- MT_QUIRK_CONTACT_CNT_ACCURATE |
- MT_QUIRK_SEPARATE_APP_REPORT,
+@@ -402,6 +412,16 @@ static const struct mt_class mt_classes[] = {
+ MT_QUIRK_ALWAYS_VALID |
+ MT_QUIRK_CONTACT_CNT_ACCURATE,
},
+ { .name = MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER,
+ .quirks = MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT |
@@ -106,7 +106,7 @@ index 99812c0f830b..0b3b51e37149 100644
{ }
};
-@@ -1744,6 +1764,69 @@ static void mt_expired_timeout(struct timer_list *t)
+@@ -1751,6 +1771,69 @@ static void mt_expired_timeout(struct timer_list *t)
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
}
@@ -176,7 +176,7 @@ index 99812c0f830b..0b3b51e37149 100644
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret, i;
-@@ -1767,6 +1850,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
+@@ -1774,6 +1857,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
hid_set_drvdata(hdev, td);
@@ -186,7 +186,7 @@ index 99812c0f830b..0b3b51e37149 100644
INIT_LIST_HEAD(&td->applications);
INIT_LIST_HEAD(&td->reports);
-@@ -1805,15 +1891,19 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
+@@ -1812,8 +1898,10 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
timer_setup(&td->release_timer, mt_expired_timeout, 0);
ret = hid_parse(hdev);
@@ -198,6 +198,8 @@ index 99812c0f830b..0b3b51e37149 100644
if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID)
mt_fix_const_fields(hdev, HID_DG_CONTACTID);
+@@ -1822,8 +1910,10 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ hdev->quirks |= HID_QUIRK_NOGET;
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret)
@@ -208,7 +210,7 @@ index 99812c0f830b..0b3b51e37149 100644
ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
if (ret)
-@@ -1863,6 +1953,7 @@ static void mt_remove(struct hid_device *hdev)
+@@ -1873,6 +1963,7 @@ static void mt_remove(struct hid_device *hdev)
{
struct mt_device *td = hid_get_drvdata(hdev);
@@ -216,7 +218,7 @@ index 99812c0f830b..0b3b51e37149 100644
del_timer_sync(&td->release_timer);
sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
-@@ -2267,6 +2358,11 @@ static const struct hid_device_id mt_devices[] = {
+@@ -2299,6 +2390,11 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
USB_DEVICE_ID_XIROKU_CSR2) },
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0021-hid-multitouch-Add-support-for-surface-pro-type-cove.patch b/packages/l/linux-current/files/patches/hardware/surface/0019-hid-multitouch-Add-support-for-surface-pro-type-cove.patch
similarity index 91%
rename from packages/l/linux-current/files/patches/hardware/surface/0021-hid-multitouch-Add-support-for-surface-pro-type-cove.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0019-hid-multitouch-Add-support-for-surface-pro-type-cove.patch
index fe3e304c5cf..7eafeff5807 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0021-hid-multitouch-Add-support-for-surface-pro-type-cove.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0019-hid-multitouch-Add-support-for-surface-pro-type-cove.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJungkamp
Date: Fri, 25 Feb 2022 12:04:25 +0100
-Subject: [PATCH 21/37] hid/multitouch: Add support for surface pro type cover
+Subject: [PATCH 19/34] hid/multitouch: Add support for surface pro type cover
tablet switch
The Surface Pro Type Cover has several non standard HID usages in it's
@@ -27,7 +27,7 @@ Patchset: surface-typecover
1 file changed, 122 insertions(+), 26 deletions(-)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
-index 0b3b51e37149..481b97dce830 100644
+index 08fee06fb5fc..f6664049f46d 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -77,6 +77,7 @@ MODULE_LICENSE("GPL");
@@ -47,7 +47,7 @@ index 0b3b51e37149..481b97dce830 100644
enum latency_mode {
HID_LATENCY_NORMAL = 0,
-@@ -408,6 +411,7 @@ static const struct mt_class mt_classes[] = {
+@@ -414,6 +417,7 @@ static const struct mt_class mt_classes[] = {
},
{ .name = MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER,
.quirks = MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT |
@@ -55,7 +55,7 @@ index 0b3b51e37149..481b97dce830 100644
MT_QUIRK_ALWAYS_VALID |
MT_QUIRK_IGNORE_DUPLICATES |
MT_QUIRK_HOVERING |
-@@ -1389,6 +1393,9 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -1395,6 +1399,9 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
field->application != HID_CP_CONSUMER_CONTROL &&
field->application != HID_GD_WIRELESS_RADIO_CTLS &&
field->application != HID_GD_SYSTEM_MULTIAXIS &&
@@ -65,7 +65,7 @@ index 0b3b51e37149..481b97dce830 100644
!(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS &&
application->quirks & MT_QUIRK_ASUS_CUSTOM_UP))
return -1;
-@@ -1416,6 +1423,21 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -1422,6 +1429,21 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
return 1;
}
@@ -87,7 +87,7 @@ index 0b3b51e37149..481b97dce830 100644
if (rdata->is_mt_collection)
return mt_touch_input_mapping(hdev, hi, field, usage, bit, max,
application);
-@@ -1437,6 +1459,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+@@ -1443,6 +1465,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
{
struct mt_device *td = hid_get_drvdata(hdev);
struct mt_report_data *rdata;
@@ -95,7 +95,7 @@ index 0b3b51e37149..481b97dce830 100644
rdata = mt_find_report_data(td, field->report);
if (rdata && rdata->is_mt_collection) {
-@@ -1444,6 +1467,19 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+@@ -1450,6 +1473,19 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
return -1;
}
@@ -115,7 +115,7 @@ index 0b3b51e37149..481b97dce830 100644
/* let hid-core decide for the others */
return 0;
}
-@@ -1453,11 +1489,21 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
+@@ -1459,11 +1495,21 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
{
struct mt_device *td = hid_get_drvdata(hid);
struct mt_report_data *rdata;
@@ -137,7 +137,7 @@ index 0b3b51e37149..481b97dce830 100644
return 0;
}
-@@ -1634,6 +1680,42 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app)
+@@ -1641,6 +1687,42 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app)
app->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
}
@@ -180,7 +180,7 @@ index 0b3b51e37149..481b97dce830 100644
static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
{
struct mt_device *td = hid_get_drvdata(hdev);
-@@ -1682,6 +1764,13 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
+@@ -1689,6 +1771,13 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
/* force BTN_STYLUS to allow tablet matching in udev */
__set_bit(BTN_STYLUS, hi->input->keybit);
break;
@@ -194,7 +194,7 @@ index 0b3b51e37149..481b97dce830 100644
default:
suffix = "UNKNOWN";
break;
-@@ -1764,30 +1853,6 @@ static void mt_expired_timeout(struct timer_list *t)
+@@ -1771,30 +1860,6 @@ static void mt_expired_timeout(struct timer_list *t)
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
}
@@ -225,7 +225,7 @@ index 0b3b51e37149..481b97dce830 100644
static void update_keyboard_backlight(struct hid_device *hdev, bool enabled)
{
struct usb_device *udev = hid_to_usb_dev(hdev);
-@@ -1796,8 +1861,9 @@ static void update_keyboard_backlight(struct hid_device *hdev, bool enabled)
+@@ -1803,8 +1868,9 @@ static void update_keyboard_backlight(struct hid_device *hdev, bool enabled)
/* Wake up the device in case it's already suspended */
pm_runtime_get_sync(&udev->dev);
@@ -237,7 +237,7 @@ index 0b3b51e37149..481b97dce830 100644
hid_err(hdev, "couldn't find backlight field\n");
goto out;
}
-@@ -1931,13 +1997,24 @@ static int mt_suspend(struct hid_device *hdev, pm_message_t state)
+@@ -1941,13 +2007,24 @@ static int mt_suspend(struct hid_device *hdev, pm_message_t state)
static int mt_reset_resume(struct hid_device *hdev)
{
@@ -262,7 +262,7 @@ index 0b3b51e37149..481b97dce830 100644
/* Some Elan legacy devices require SET_IDLE to be set on resume.
* It should be safe to send it to other devices too.
* Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */
-@@ -1946,12 +2023,31 @@ static int mt_resume(struct hid_device *hdev)
+@@ -1956,12 +2033,31 @@ static int mt_resume(struct hid_device *hdev)
mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0022-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch b/packages/l/linux-current/files/patches/hardware/surface/0020-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch
similarity index 92%
rename from packages/l/linux-current/files/patches/hardware/surface/0022-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0020-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch
index e395e4c1123..fd2efb8b12f 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0022-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0020-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Sun, 19 Feb 2023 22:12:24 +0100
-Subject: [PATCH 22/37] PCI: Add quirk to prevent calling shutdown mehtod
+Subject: [PATCH 20/34] PCI: Add quirk to prevent calling shutdown mehtod
Work around buggy EFI firmware: On some Microsoft Surface devices
(Surface Pro 9 and Surface Laptop 5) the EFI ResetSystem call with
@@ -23,7 +23,7 @@ Patchset: surface-shutdown
3 files changed, 40 insertions(+)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
-index f412ef73a6e4..9892cd72dd2c 100644
+index 35270172c833..529779994ef6 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -505,6 +505,9 @@ static void pci_device_shutdown(struct device *dev)
@@ -37,10 +37,10 @@ index f412ef73a6e4..9892cd72dd2c 100644
if (drv && drv->shutdown)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
-index 5d57ea27dbc4..7009cb320af1 100644
+index 8103bc24a54e..e8fa8d810925 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
-@@ -6290,3 +6290,39 @@ static void pci_mask_replay_timer_timeout(struct pci_dev *pdev)
+@@ -6301,3 +6301,39 @@ static void pci_mask_replay_timer_timeout(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9750, pci_mask_replay_timer_timeout);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9755, pci_mask_replay_timer_timeout);
#endif
@@ -81,10 +81,10 @@ index 5d57ea27dbc4..7009cb320af1 100644
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x466d, quirk_no_shutdown); // Thunderbolt 4 NHI
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x46a8, quirk_no_shutdown); // GPU
diff --git a/include/linux/pci.h b/include/linux/pci.h
-index 4cf89a4b4cbc..bb633c76d3a5 100644
+index 4e77c4230c0a..a4b0e6ef6cfe 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
-@@ -466,6 +466,7 @@ struct pci_dev {
+@@ -467,6 +467,7 @@ struct pci_dev {
unsigned int no_command_memory:1; /* No PCI_COMMAND_MEMORY */
unsigned int rom_bar_overlap:1; /* ROM BAR disable broken */
unsigned int rom_attr_enabled:1; /* Display of ROM attribute enabled? */
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0023-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch b/packages/l/linux-current/files/patches/hardware/surface/0021-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch
similarity index 95%
rename from packages/l/linux-current/files/patches/hardware/surface/0023-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0021-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch
index 1c3c6d78072..7f4e23bf6de 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0023-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0021-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Sun, 12 Mar 2023 01:41:57 +0100
-Subject: [PATCH 23/37] platform/surface: gpe: Add support for Surface Pro 9
+Subject: [PATCH 21/34] platform/surface: gpe: Add support for Surface Pro 9
Add the lid GPE used by the Surface Pro 9.
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0024-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch b/packages/l/linux-current/files/patches/hardware/surface/0022-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch
similarity index 95%
rename from packages/l/linux-current/files/patches/hardware/surface/0024-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0022-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch
index 520e7409d61..830df4bf4a1 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0024-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0022-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hans de Goede
Date: Sun, 10 Oct 2021 20:56:57 +0200
-Subject: [PATCH 24/37] ACPI: delay enumeration of devices with a _DEP pointing
+Subject: [PATCH 22/34] ACPI: delay enumeration of devices with a _DEP pointing
to an INT3472 device
The clk and regulator frameworks expect clk/regulator consumer-devices
@@ -58,10 +58,10 @@ Patchset: cameras
1 file changed, 3 insertions(+)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
-index 22ae7829a915..0fe281280316 100644
+index 7ecc401fb97f..e35185de1902 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
-@@ -2185,6 +2185,9 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used,
+@@ -2205,6 +2205,9 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used,
static void acpi_default_enumeration(struct acpi_device *device)
{
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0025-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch b/packages/l/linux-current/files/patches/hardware/surface/0023-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch
similarity index 89%
rename from packages/l/linux-current/files/patches/hardware/surface/0025-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0023-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch
index 12f8823ee28..4e7e9f6939a 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0025-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0023-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: zouxiaoh
Date: Fri, 25 Jun 2021 08:52:59 +0800
-Subject: [PATCH 25/37] iommu: intel-ipu: use IOMMU passthrough mode for Intel
+Subject: [PATCH 23/34] iommu: intel-ipu: use IOMMU passthrough mode for Intel
IPUs
Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
@@ -25,7 +25,7 @@ Patchset: cameras
1 file changed, 30 insertions(+)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
-index 5df658b9811b..7e3c58c872a7 100644
+index f18d5635d2f6..361f4c178efb 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -45,6 +45,13 @@
@@ -42,7 +42,7 @@ index 5df658b9811b..7e3c58c872a7 100644
#define IOAPIC_RANGE_START (0xfee00000)
#define IOAPIC_RANGE_END (0xfeefffff)
#define IOVA_START_ADDR (0x1000)
-@@ -223,12 +230,14 @@ int intel_iommu_enabled = 0;
+@@ -214,12 +221,14 @@ int intel_iommu_enabled = 0;
EXPORT_SYMBOL_GPL(intel_iommu_enabled);
static int dmar_map_ipts = 1;
@@ -57,7 +57,7 @@ index 5df658b9811b..7e3c58c872a7 100644
#define IDENTMAP_IPTS 16
const struct iommu_ops intel_iommu_ops;
-@@ -2164,6 +2173,9 @@ static int device_def_domain_type(struct device *dev)
+@@ -2054,6 +2063,9 @@ static int device_def_domain_type(struct device *dev)
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
return IOMMU_DOMAIN_IDENTITY;
@@ -67,7 +67,7 @@ index 5df658b9811b..7e3c58c872a7 100644
if ((iommu_identity_mapping & IDENTMAP_IPTS) && IS_IPTS(pdev))
return IOMMU_DOMAIN_IDENTITY;
}
-@@ -2466,6 +2478,9 @@ static int __init init_dmars(void)
+@@ -2354,6 +2366,9 @@ static int __init init_dmars(void)
iommu_set_root_entry(iommu);
}
@@ -77,7 +77,7 @@ index 5df658b9811b..7e3c58c872a7 100644
if (!dmar_map_ipts)
iommu_identity_mapping |= IDENTMAP_IPTS;
-@@ -4712,6 +4727,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev)
+@@ -4662,6 +4677,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev)
disable_igfx_iommu = 1;
}
@@ -96,7 +96,7 @@ index 5df658b9811b..7e3c58c872a7 100644
static void quirk_iommu_ipts(struct pci_dev *dev)
{
if (!IS_IPTS(dev))
-@@ -4759,6 +4786,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
+@@ -4709,6 +4736,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0026-platform-x86-int3472-Enable-I2c-daisy-chain.patch b/packages/l/linux-current/files/patches/hardware/surface/0024-platform-x86-int3472-Enable-I2c-daisy-chain.patch
similarity index 94%
rename from packages/l/linux-current/files/patches/hardware/surface/0026-platform-x86-int3472-Enable-I2c-daisy-chain.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0024-platform-x86-int3472-Enable-I2c-daisy-chain.patch
index 4b184b8c305..b514626029c 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0026-platform-x86-int3472-Enable-I2c-daisy-chain.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0024-platform-x86-int3472-Enable-I2c-daisy-chain.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Scally
Date: Sun, 10 Oct 2021 20:57:02 +0200
-Subject: [PATCH 26/37] platform/x86: int3472: Enable I2c daisy chain
+Subject: [PATCH 24/34] platform/x86: int3472: Enable I2c daisy chain
The TPS68470 PMIC has an I2C passthrough mode through which I2C traffic
can be forwarded to a device connected to the PMIC as though it were
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0027-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch b/packages/l/linux-current/files/patches/hardware/surface/0025-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch
similarity index 91%
rename from packages/l/linux-current/files/patches/hardware/surface/0027-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0025-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch
index 003854db06c..95d25f51e21 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0027-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0025-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Scally
Date: Thu, 2 Mar 2023 12:59:39 +0000
-Subject: [PATCH 27/37] platform/x86: int3472: Remap reset GPIO for INT347E
+Subject: [PATCH 25/34] platform/x86: int3472: Remap reset GPIO for INT347E
ACPI _HID INT347E represents the OmniVision 7251 camera sensor. The
driver for this sensor expects a single pin named "enable", but on
@@ -20,10 +20,10 @@ Patchset: cameras
1 file changed, 15 insertions(+)
diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
-index 07b302e09340..baad1e50ca81 100644
+index 3de463c3d13b..0a012eeed30a 100644
--- a/drivers/platform/x86/intel/int3472/discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
-@@ -83,12 +83,27 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
+@@ -80,12 +80,27 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
const char *func, u32 polarity)
{
int ret;
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0028-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch b/packages/l/linux-current/files/patches/hardware/surface/0026-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch
similarity index 95%
rename from packages/l/linux-current/files/patches/hardware/surface/0028-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0026-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch
index 3c23b673f27..2ddb59d0a02 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0028-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0026-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Scally
Date: Tue, 21 Mar 2023 13:45:26 +0000
-Subject: [PATCH 28/37] media: i2c: Clarify that gain is Analogue gain in
+Subject: [PATCH 26/34] media: i2c: Clarify that gain is Analogue gain in
OV7251
Update the control ID for the gain control in the ov7251 driver to
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0029-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch b/packages/l/linux-current/files/patches/hardware/surface/0027-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch
similarity index 96%
rename from packages/l/linux-current/files/patches/hardware/surface/0029-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0027-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch
index 9e95752dd2e..c03d6cea0f7 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0029-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0027-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Scally
Date: Wed, 22 Mar 2023 11:01:42 +0000
-Subject: [PATCH 29/37] media: v4l2-core: Acquire privacy led in
+Subject: [PATCH 27/34] media: v4l2-core: Acquire privacy led in
v4l2_async_register_subdev()
The current call to v4l2_subdev_get_privacy_led() is contained in
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0030-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch b/packages/l/linux-current/files/patches/hardware/surface/0028-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch
similarity index 95%
rename from packages/l/linux-current/files/patches/hardware/surface/0030-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0028-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch
index 56651d1ff8c..cc4184f8927 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0030-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0028-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kate Hsuan
Date: Tue, 21 Mar 2023 23:37:16 +0800
-Subject: [PATCH 30/37] platform: x86: int3472: Add MFD cell for tps68470 LED
+Subject: [PATCH 28/34] platform: x86: int3472: Add MFD cell for tps68470 LED
Add MFD cell for tps68470-led.
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0031-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch b/packages/l/linux-current/files/patches/hardware/surface/0029-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch
similarity index 95%
rename from packages/l/linux-current/files/patches/hardware/surface/0031-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0029-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch
index e1af9723315..a11c0d4ad7b 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0031-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0029-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kate Hsuan
Date: Tue, 21 Mar 2023 23:37:17 +0800
-Subject: [PATCH 31/37] include: mfd: tps68470: Add masks for LEDA and LEDB
+Subject: [PATCH 29/34] include: mfd: tps68470: Add masks for LEDA and LEDB
Add flags for both LEDA(TPS68470_ILEDCTL_ENA), LEDB
(TPS68470_ILEDCTL_ENB), and current control mask for LEDB
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0032-leds-tps68470-Add-LED-control-for-tps68470.patch b/packages/l/linux-current/files/patches/hardware/surface/0030-leds-tps68470-Add-LED-control-for-tps68470.patch
similarity index 97%
rename from packages/l/linux-current/files/patches/hardware/surface/0032-leds-tps68470-Add-LED-control-for-tps68470.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0030-leds-tps68470-Add-LED-control-for-tps68470.patch
index 7f229698806..4759dfa4cae 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0032-leds-tps68470-Add-LED-control-for-tps68470.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0030-leds-tps68470-Add-LED-control-for-tps68470.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kate Hsuan
Date: Tue, 21 Mar 2023 23:37:18 +0800
-Subject: [PATCH 32/37] leds: tps68470: Add LED control for tps68470
+Subject: [PATCH 30/34] leds: tps68470: Add LED control for tps68470
There are two LED controllers, LEDA indicator LED and LEDB flash LED for
tps68470. LEDA can be enabled by setting TPS68470_ILEDCTL_ENA. Moreover,
@@ -21,10 +21,10 @@ Patchset: cameras
create mode 100644 drivers/leds/leds-tps68470.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
-index 8d9d8da376e4..d8597897aa83 100644
+index b784bb74a837..f8d8fcfacac2 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
-@@ -933,6 +933,18 @@ config LEDS_TPS6105X
+@@ -941,6 +941,18 @@ config LEDS_TPS6105X
It is a single boost converter primarily for white LEDs and
audio amplifiers.
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0034-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch b/packages/l/linux-current/files/patches/hardware/surface/0031-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch
similarity index 94%
rename from packages/l/linux-current/files/patches/hardware/surface/0034-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0031-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch
index 437046bf9e1..d726a832f6a 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0034-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0031-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: mojyack
Date: Tue, 26 Mar 2024 05:55:44 +0900
-Subject: [PATCH 34/37] media: i2c: dw9719: fix probe error on surface go 2
+Subject: [PATCH 31/34] media: i2c: dw9719: fix probe error on surface go 2
On surface go 2, sometimes probing dw9719 fails with "dw9719: probe of i2c-INT347A:00-VCM failed with error -121".
The -121(-EREMOTEIO) is came from drivers/i2c/busses/i2c-designware-common.c:575, and indicates the initialize occurs too early.
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0035-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch b/packages/l/linux-current/files/patches/hardware/surface/0032-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch
similarity index 96%
rename from packages/l/linux-current/files/patches/hardware/surface/0035-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0032-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch
index 30e96b97355..89a7625f285 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0035-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0032-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sachi King
Date: Sat, 29 May 2021 17:47:38 +1000
-Subject: [PATCH 35/37] ACPI: Add quirk for Surface Laptop 4 AMD missing irq 7
+Subject: [PATCH 32/34] ACPI: Add quirk for Surface Laptop 4 AMD missing irq 7
override
This patch is the work of Thomas Gleixner and is
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0036-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch b/packages/l/linux-current/files/patches/hardware/surface/0033-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch
similarity index 95%
rename from packages/l/linux-current/files/patches/hardware/surface/0036-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0033-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch
index 49ca60caf73..1cf0a3ed62c 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0036-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0033-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maximilian Luz
Date: Thu, 3 Jun 2021 14:04:26 +0200
-Subject: [PATCH 36/37] ACPI: Add AMD 13" Surface Laptop 4 model to irq 7
+Subject: [PATCH 33/34] ACPI: Add AMD 13" Surface Laptop 4 model to irq 7
override quirk
The 13" version of the Surface Laptop 4 has the same problem as the 15"
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0033-media-staging-ipu3-imgu-Fix-multiple-calls-of-s_stre.patch b/packages/l/linux-current/files/patches/hardware/surface/0033-media-staging-ipu3-imgu-Fix-multiple-calls-of-s_stre.patch
deleted file mode 100644
index 8b3abb4aede..00000000000
--- a/packages/l/linux-current/files/patches/hardware/surface/0033-media-staging-ipu3-imgu-Fix-multiple-calls-of-s_stre.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: mojyack
-Date: Sat, 3 Feb 2024 12:59:53 +0900
-Subject: [PATCH 33/37] media: staging: ipu3-imgu: Fix multiple calls of
- s_stream on stream stop
-
-Adapt to 009905e "media: v4l2-subdev: Document and enforce .s_stream() requirements"
-
-Patchset: cameras
----
- drivers/staging/media/ipu3/ipu3-v4l2.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
-index 3df58eb3e882..81aff2d5d898 100644
---- a/drivers/staging/media/ipu3/ipu3-v4l2.c
-+++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
-@@ -538,18 +538,18 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq)
-
- WARN_ON(!node->enabled);
-
-- pipe = node->pipe;
-- dev_dbg(dev, "Try to stream off node [%u][%u]", pipe, node->id);
-- imgu_pipe = &imgu->imgu_pipe[pipe];
-- r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, video, s_stream, 0);
-- if (r)
-- dev_err(&imgu->pci_dev->dev,
-- "failed to stop subdev streaming\n");
--
- mutex_lock(&imgu->streaming_lock);
- /* Was this the first node with streaming disabled? */
- if (imgu->streaming && imgu_all_nodes_streaming(imgu, node)) {
- /* Yes, really stop streaming now */
-+ pipe = node->pipe;
-+ dev_dbg(dev, "Try to stream off node [%u][%u]", pipe, node->id);
-+ imgu_pipe = &imgu->imgu_pipe[pipe];
-+ r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, video, s_stream, 0);
-+ if (r)
-+ dev_err(&imgu->pci_dev->dev,
-+ "failed to stop subdev streaming\n");
-+
- dev_dbg(dev, "IMGU streaming is ready to stop");
- r = imgu_s_stream(imgu, false);
- if (!r)
diff --git a/packages/l/linux-current/files/patches/hardware/surface/0037-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch b/packages/l/linux-current/files/patches/hardware/surface/0034-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch
similarity index 98%
rename from packages/l/linux-current/files/patches/hardware/surface/0037-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch
rename to packages/l/linux-current/files/patches/hardware/surface/0034-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch
index ccb0e70acad..2d95786a7c4 100644
--- a/packages/l/linux-current/files/patches/hardware/surface/0037-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch
+++ b/packages/l/linux-current/files/patches/hardware/surface/0034-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch
@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Bart Groeneveld | GPX Solutions B.V"
Date: Mon, 5 Dec 2022 16:08:46 +0100
-Subject: [PATCH 37/37] acpi: allow usage of acpi_tad on HW-reduced platforms
+Subject: [PATCH 34/34] acpi: allow usage of acpi_tad on HW-reduced platforms
The specification [1] allows so-called HW-reduced platforms,
which do not implement everything, especially the wakeup related stuff.
diff --git a/packages/l/linux-current/files/patches/performance/0001-linux6.11.y-bore5.7.3.patch b/packages/l/linux-current/files/patches/performance/0001-linux6.12.y-bore5.7.13.patch
similarity index 83%
rename from packages/l/linux-current/files/patches/performance/0001-linux6.11.y-bore5.7.3.patch
rename to packages/l/linux-current/files/patches/performance/0001-linux6.12.y-bore5.7.13.patch
index c96f3ab8423..4baa1b0ce78 100644
--- a/packages/l/linux-current/files/patches/performance/0001-linux6.11.y-bore5.7.3.patch
+++ b/packages/l/linux-current/files/patches/performance/0001-linux6.12.y-bore5.7.13.patch
@@ -1,30 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Masahito S
-Date: Thu, 7 Nov 2024 02:22:15 +0900
-Subject: [PATCH] linux6.11.y-bore5.7.3
+Date: Thu, 12 Dec 2024 06:57:02 +0900
+Subject: [PATCH] linux6.12.y-bore5.7.13
---
- include/linux/sched.h | 20 +-
- include/linux/sched/bore.h | 37 ++++
+ include/linux/sched.h | 17 ++
+ include/linux/sched/bore.h | 40 ++++
init/Kconfig | 17 ++
kernel/Kconfig.hz | 17 ++
kernel/fork.c | 5 +
kernel/sched/Makefile | 1 +
- kernel/sched/bore.c | 381 +++++++++++++++++++++++++++++++++++++
- kernel/sched/core.c | 7 +
+ kernel/sched/bore.c | 423 +++++++++++++++++++++++++++++++++++++
+ kernel/sched/core.c | 6 +
kernel/sched/debug.c | 61 +++++-
- kernel/sched/fair.c | 85 ++++++++-
- kernel/sched/features.h | 4 +
+ kernel/sched/fair.c | 75 ++++++-
kernel/sched/sched.h | 9 +
- 12 files changed, 639 insertions(+), 5 deletions(-)
+ 11 files changed, 666 insertions(+), 5 deletions(-)
create mode 100644 include/linux/sched/bore.h
create mode 100644 kernel/sched/bore.c
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 1c771ea4481d..0c6ac0ac8e60 100644
+index bb343136ddd0..c86185f87e7b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
-@@ -535,6 +535,14 @@ struct sched_statistics {
+@@ -538,6 +538,14 @@ struct sched_statistics {
#endif /* CONFIG_SCHEDSTATS */
} ____cacheline_aligned;
@@ -39,15 +38,7 @@ index 1c771ea4481d..0c6ac0ac8e60 100644
struct sched_entity {
/* For load-balancing: */
struct load_weight load;
-@@ -543,12 +551,22 @@ struct sched_entity {
- u64 min_vruntime;
-
- struct list_head group_node;
-- unsigned int on_rq;
-+ unsigned char on_rq;
-+ unsigned char rel_deadline;
-
- u64 exec_start;
+@@ -557,6 +565,15 @@ struct sched_entity {
u64 sum_exec_runtime;
u64 prev_sum_exec_runtime;
u64 vruntime;
@@ -65,16 +56,17 @@ index 1c771ea4481d..0c6ac0ac8e60 100644
diff --git a/include/linux/sched/bore.h b/include/linux/sched/bore.h
new file mode 100644
-index 000000000000..12a613a94ff0
+index 000000000000..4f3d3cbefe3c
--- /dev/null
+++ b/include/linux/sched/bore.h
-@@ -0,0 +1,37 @@
+@@ -0,0 +1,40 @@
+
+#include
+#include
+
+#ifndef _LINUX_SCHED_BORE_H
+#define _LINUX_SCHED_BORE_H
++#define SCHED_BORE_VERSION "5.7.13"
+
+#ifdef CONFIG_SCHED_BORE
+extern u8 __read_mostly sched_bore;
@@ -85,6 +77,7 @@ index 000000000000..12a613a94ff0
+extern u8 __read_mostly sched_burst_parity_threshold;
+extern u8 __read_mostly sched_burst_penalty_offset;
+extern uint __read_mostly sched_burst_penalty_scale;
++extern uint __read_mostly sched_burst_cache_stop_count;
+extern uint __read_mostly sched_burst_cache_lifetime;
+extern uint __read_mostly sched_deadline_boost_mask;
+
@@ -101,16 +94,17 @@ index 000000000000..12a613a94ff0
+ struct task_struct *p, struct task_struct *parent, u64 clone_flags);
+
+extern void init_task_bore(struct task_struct *p);
++extern void sched_bore_init(void);
+
+extern void reweight_entity(
+ struct cfs_rq *cfs_rq, struct sched_entity *se, unsigned long weight);
+#endif // CONFIG_SCHED_BORE
+#endif // _LINUX_SCHED_BORE_H
diff --git a/init/Kconfig b/init/Kconfig
-index 5783a0b87517..b648ed538c59 100644
+index 7256fa127530..6bd6c8cab18b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
-@@ -1297,6 +1297,23 @@ config CHECKPOINT_RESTORE
+@@ -1341,6 +1341,23 @@ config CHECKPOINT_RESTORE
If unsure, say N here.
@@ -162,10 +156,10 @@ index 38ef6d06888e..253c566b5946 100644
config SCHED_HRTICK
def_bool HIGH_RES_TIMERS
diff --git a/kernel/fork.c b/kernel/fork.c
-index 6b97fb2ac4af..7dc42ef458e1 100644
+index ce8be55e5e04..fa1dab6e7dec 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
-@@ -111,6 +111,8 @@
+@@ -113,6 +113,8 @@
#include
#include
@@ -174,7 +168,7 @@ index 6b97fb2ac4af..7dc42ef458e1 100644
#include
#define CREATE_TRACE_POINTS
-@@ -2341,6 +2343,9 @@ __latent_entropy struct task_struct *copy_process(
+@@ -2364,6 +2366,9 @@ __latent_entropy struct task_struct *copy_process(
retval = sched_fork(clone_flags, p);
if (retval)
goto bad_fork_cleanup_policy;
@@ -195,15 +189,16 @@ index 976092b7bd45..293aad675444 100644
+obj-y += bore.o
diff --git a/kernel/sched/bore.c b/kernel/sched/bore.c
new file mode 100644
-index 000000000000..cd7e8a8d6075
+index 000000000000..da1edca15414
--- /dev/null
+++ b/kernel/sched/bore.c
-@@ -0,0 +1,381 @@
+@@ -0,0 +1,423 @@
+/*
+ * Burst-Oriented Response Enhancer (BORE) CPU Scheduler
+ * Copyright (C) 2021-2024 Masahito Suzuki
+ */
+#include
++#include
+#include
+#include "sched.h"
+
@@ -216,7 +211,8 @@ index 000000000000..cd7e8a8d6075
+u8 __read_mostly sched_burst_parity_threshold = 2;
+u8 __read_mostly sched_burst_penalty_offset = 24;
+uint __read_mostly sched_burst_penalty_scale = 1280;
-+uint __read_mostly sched_burst_cache_lifetime = 60000000;
++uint __read_mostly sched_burst_cache_stop_count = 64;
++uint __read_mostly sched_burst_cache_lifetime = 75000000;
+uint __read_mostly sched_deadline_boost_mask = ENQUEUE_INITIAL
+ | ENQUEUE_WAKEUP;
+static int __maybe_unused sixty_four = 64;
@@ -320,7 +316,7 @@ index 000000000000..cd7e8a8d6075
+}
+
+static inline bool task_is_bore_eligible(struct task_struct *p)
-+{return p->sched_class == &fair_sched_class;}
++{return p && p->sched_class == &fair_sched_class && !p->exit_state;}
+
+static void reset_task_weights_bore(void) {
+ struct task_struct *task;
@@ -349,10 +345,13 @@ index 000000000000..cd7e8a8d6075
+ return 0;
+}
+
-+static u32 count_child_tasks(struct task_struct *p) {
-+ struct task_struct *child;
++#define for_each_child(p, t) \
++ list_for_each_entry(t, &(p)->children, sibling)
++
++static u32 count_children_max2(struct task_struct *p) {
+ u32 cnt = 0;
-+ list_for_each_entry(child, &p->children, sibling) {cnt++;}
++ struct task_struct *child;
++ for_each_child(p, child) {if (2 <= ++cnt) break;}
+ return cnt;
+}
+
@@ -371,7 +370,7 @@ index 000000000000..cd7e8a8d6075
+ u32 cnt = 0, sum = 0;
+ struct task_struct *child;
+
-+ list_for_each_entry(child, &p->children, sibling) {
++ for_each_child(p, child) {
+ if (!task_is_bore_eligible(child)) continue;
+ cnt++;
+ sum += child->se.burst_penalty;
@@ -380,8 +379,13 @@ index 000000000000..cd7e8a8d6075
+ update_burst_cache(&p->se.child_burst, p, cnt, sum, now);
+}
+
-+static inline u8 inherit_burst_direct(struct task_struct *p, u64 now) {
++static inline u8 inherit_burst_direct(
++ struct task_struct *p, u64 now, u64 clone_flags) {
+ struct task_struct *parent = p;
++
++ if (clone_flags & CLONE_PARENT)
++ parent = parent->real_parent;
++
+ if (burst_cache_expired(&parent->se.child_burst, now))
+ update_child_burst_direct(parent, now);
+
@@ -393,9 +397,9 @@ index 000000000000..cd7e8a8d6075
+ u32 cnt = 0, dcnt = 0, sum = 0;
+ struct task_struct *child, *dec;
+
-+ list_for_each_entry(child, &p->children, sibling) {
++ for_each_child(p, child) {
+ dec = child;
-+ while ((dcnt = count_child_tasks(dec)) == 1)
++ while ((dcnt = count_children_max2(dec)) == 1)
+ dec = list_first_entry(&dec->children, struct task_struct, sibling);
+
+ if (!dcnt || !depth) {
@@ -407,6 +411,7 @@ index 000000000000..cd7e8a8d6075
+ if (!burst_cache_expired(&dec->se.child_burst, now)) {
+ cnt += dec->se.child_burst.count;
+ sum += (u32)dec->se.child_burst.score * dec->se.child_burst.count;
++ if (sched_burst_cache_stop_count <= cnt) break;
+ continue;
+ }
+ update_child_burst_topological(dec, now, depth - 1, &cnt, &sum);
@@ -417,12 +422,23 @@ index 000000000000..cd7e8a8d6075
+ *asum += sum;
+}
+
-+static inline u8 inherit_burst_topological(struct task_struct *p, u64 now) {
++static inline u8 inherit_burst_topological(
++ struct task_struct *p, u64 now, u64 clone_flags) {
+ struct task_struct *anc = p;
+ u32 cnt = 0, sum = 0;
++ u32 base_child_cnt = 0;
+
-+ while (anc->real_parent != anc && count_child_tasks(anc) == 1)
++ if (clone_flags & CLONE_PARENT) {
+ anc = anc->real_parent;
++ base_child_cnt = 1;
++ }
++
++ for (struct task_struct *next;
++ anc != (next = anc->real_parent) &&
++ count_children_max2(anc) <= base_child_cnt;) {
++ anc = next;
++ base_child_cnt = 1;
++ }
+
+ if (burst_cache_expired(&anc->se.child_burst, now))
+ update_child_burst_topological(
@@ -445,7 +461,7 @@ index 000000000000..cd7e8a8d6075
+}
+
+static inline u8 inherit_burst_tg(struct task_struct *p, u64 now) {
-+ struct task_struct *parent = p->group_leader;
++ struct task_struct *parent = rcu_dereference(p->group_leader);
+ if (burst_cache_expired(&parent->se.group_burst, now))
+ update_tg_burst(parent, now);
+
@@ -454,16 +470,24 @@ index 000000000000..cd7e8a8d6075
+
+void sched_clone_bore(
+ struct task_struct *p, struct task_struct *parent, u64 clone_flags) {
++ u64 now;
++ u8 penalty;
++
+ if (!task_is_bore_eligible(p)) return;
+
-+ u64 now = ktime_get_ns();
-+ read_lock(&tasklist_lock);
-+ u8 penalty = (clone_flags & CLONE_THREAD) ?
-+ inherit_burst_tg(parent, now) :
-+ likely(sched_burst_fork_atavistic) ?
-+ inherit_burst_topological(parent, now):
-+ inherit_burst_direct(parent, now);
-+ read_unlock(&tasklist_lock);
++ if (clone_flags & CLONE_THREAD) {
++ rcu_read_lock();
++ now = jiffies_to_nsecs(jiffies);
++ penalty = inherit_burst_tg(parent, now);
++ rcu_read_unlock();
++ } else {
++ read_lock(&tasklist_lock);
++ now = jiffies_to_nsecs(jiffies);
++ penalty = likely(sched_burst_fork_atavistic) ?
++ inherit_burst_topological(parent, now, clone_flags):
++ inherit_burst_direct(parent, now, clone_flags);
++ read_unlock(&tasklist_lock);
++ }
+
+ struct sched_entity *se = &p->se;
+ revolve_burst_penalty(se);
@@ -483,6 +507,11 @@ index 000000000000..cd7e8a8d6075
+ memset(&p->se.group_burst, 0, sizeof(struct sched_burst_cache));
+}
+
++void __init sched_bore_init(void) {
++ printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification %s by Masahito Suzuki", SCHED_BORE_VERSION);
++ init_task_bore(&init_task);
++}
++
+#ifdef CONFIG_SYSCTL
+static struct ctl_table sched_bore_sysctls[] = {
+ {
@@ -558,6 +587,13 @@ index 000000000000..cd7e8a8d6075
+ .extra2 = &maxval_12_bits,
+ },
+ {
++ .procname = "sched_burst_cache_stop_count",
++ .data = &sched_burst_cache_stop_count,
++ .maxlen = sizeof(uint),
++ .mode = 0644,
++ .proc_handler = proc_douintvec,
++ },
++ {
+ .procname = "sched_burst_cache_lifetime",
+ .data = &sched_burst_cache_lifetime,
+ .maxlen = sizeof(uint),
@@ -581,7 +617,7 @@ index 000000000000..cd7e8a8d6075
+#endif // CONFIG_SYSCTL
+#endif // CONFIG_SCHED_BORE
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
-index 3713341c2e72..b54ae0578b2c 100644
+index 6cc12777bb11..aa131e05dbbc 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -97,6 +97,8 @@
@@ -593,20 +629,19 @@ index 3713341c2e72..b54ae0578b2c 100644
EXPORT_TRACEPOINT_SYMBOL_GPL(ipi_send_cpu);
EXPORT_TRACEPOINT_SYMBOL_GPL(ipi_send_cpumask);
-@@ -8204,6 +8206,11 @@ void __init sched_init(void)
- BUG_ON(&dl_sched_class != &stop_sched_class + 1);
+@@ -8377,6 +8379,10 @@ void __init sched_init(void)
+ BUG_ON(!sched_class_above(&ext_sched_class, &idle_sched_class));
#endif
+#ifdef CONFIG_SCHED_BORE
-+ printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification 5.7.3 by Masahito Suzuki");
-+ init_task_bore(&init_task);
++ sched_bore_init();
+#endif // CONFIG_SCHED_BORE
+
wait_bit_init();
#ifdef CONFIG_FAIR_GROUP_SCHED
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
-index c1eb9a1afd13..02d2895c4607 100644
+index f4035c7a0fa1..0edb3a216f5d 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -167,7 +167,53 @@ static const struct file_operations sched_feat_fops = {
@@ -672,7 +707,7 @@ index c1eb9a1afd13..02d2895c4607 100644
#endif /* SMP */
#ifdef CONFIG_PREEMPT_DYNAMIC
-@@ -347,13 +393,20 @@ static __init int sched_init_debug(void)
+@@ -504,13 +550,20 @@ static __init int sched_init_debug(void)
debugfs_create_file("preempt", 0644, debugfs_sched, NULL, &sched_dynamic_fops);
#endif
@@ -693,7 +728,7 @@ index c1eb9a1afd13..02d2895c4607 100644
debugfs_create_u32("migration_cost_ns", 0644, debugfs_sched, &sysctl_sched_migration_cost);
debugfs_create_u32("nr_migrate", 0644, debugfs_sched, &sysctl_sched_nr_migrate);
-@@ -596,6 +649,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
+@@ -755,6 +808,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
SPLIT_NS(schedstat_val_or_zero(p->stats.sum_sleep_runtime)),
SPLIT_NS(schedstat_val_or_zero(p->stats.sum_block_runtime)));
@@ -701,9 +736,9 @@ index c1eb9a1afd13..02d2895c4607 100644
+ SEQ_printf(m, " %2d", p->se.burst_score);
+#endif // CONFIG_SCHED_BORE
#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
-@@ -1069,6 +1125,9 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns,
+@@ -1243,6 +1299,9 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns,
P(se.load.weight);
#ifdef CONFIG_SMP
@@ -714,7 +749,7 @@ index c1eb9a1afd13..02d2895c4607 100644
P(se.avg.runnable_sum);
P(se.avg.util_sum);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
-index 1d2cbdb162a6..8666269f73b7 100644
+index 782ce70ebd1b..48dea624ccf0 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -55,6 +55,8 @@
@@ -791,7 +826,7 @@ index 1d2cbdb162a6..8666269f73b7 100644
return clamp(vlag, -limit, limit);
}
-@@ -896,6 +922,10 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq)
+@@ -926,6 +952,10 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq)
* until it gets a new slice. See the HACK in set_next_entity().
*/
if (sched_feat(RUN_TO_PARITY) && curr && curr->vlag == curr->deadline)
@@ -802,7 +837,7 @@ index 1d2cbdb162a6..8666269f73b7 100644
return curr;
/* Pick the leftmost entity if it's eligible */
-@@ -954,6 +984,7 @@ struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
+@@ -984,6 +1014,7 @@ struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
* Scheduling class statistics methods:
*/
#ifdef CONFIG_SMP
@@ -810,7 +845,7 @@ index 1d2cbdb162a6..8666269f73b7 100644
int sched_update_scaling(void)
{
unsigned int factor = get_update_sysctl_factor();
-@@ -965,6 +996,7 @@ int sched_update_scaling(void)
+@@ -995,6 +1026,7 @@ int sched_update_scaling(void)
return 0;
}
@@ -818,7 +853,7 @@ index 1d2cbdb162a6..8666269f73b7 100644
#endif
#endif
-@@ -1165,6 +1197,10 @@ static void update_curr(struct cfs_rq *cfs_rq)
+@@ -1227,6 +1259,10 @@ static void update_curr(struct cfs_rq *cfs_rq)
if (unlikely(delta_exec <= 0))
return;
@@ -827,9 +862,9 @@ index 1d2cbdb162a6..8666269f73b7 100644
+ update_burst_penalty(curr);
+#endif // CONFIG_SCHED_BORE
curr->vruntime += calc_delta_fair(delta_exec, curr);
- update_deadline(cfs_rq, curr);
+ resched = update_deadline(cfs_rq, curr);
update_min_vruntime(cfs_rq);
-@@ -3791,7 +3827,7 @@ static void reweight_eevdf(struct sched_entity *se, u64 avruntime,
+@@ -3877,7 +3913,7 @@ static void reweight_eevdf(struct sched_entity *se, u64 avruntime,
se->deadline = avruntime + vslice;
}
@@ -838,7 +873,7 @@ index 1d2cbdb162a6..8666269f73b7 100644
unsigned long weight)
{
bool curr = cfs_rq->curr == se;
-@@ -5198,6 +5234,9 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
+@@ -5286,6 +5322,9 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
*
* EEVDF: placement strategy #1 / #2
*/
@@ -848,15 +883,11 @@ index 1d2cbdb162a6..8666269f73b7 100644
if (sched_feat(PLACE_LAG) && cfs_rq->nr_running) {
struct sched_entity *curr = cfs_rq->curr;
unsigned long load;
-@@ -5268,6 +5307,16 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
-
- se->vruntime = vruntime - lag;
-
-+ if (sched_feat(PLACE_REL_DEADLINE) && se->rel_deadline) {
-+ se->deadline += se->vruntime;
-+ se->rel_deadline = 0;
-+ return;
-+ }
+@@ -5361,7 +5400,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
+ se->rel_deadline = 0;
+ return;
+ }
+-
+#ifdef CONFIG_SCHED_BORE
+ else if (likely(sched_bore))
+ vslice >>= !!(flags & sched_deadline_boost_mask);
@@ -865,42 +896,22 @@ index 1d2cbdb162a6..8666269f73b7 100644
/*
* When joining the competition; the existing tasks will be,
* on average, halfway through their slice, as such start tasks
-@@ -5377,6 +5426,7 @@ static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq);
- static void
- dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
- {
-+ bool sleep = flags & DEQUEUE_SLEEP;
- int action = UPDATE_TG;
-
- if (entity_is_task(se) && task_on_rq_migrating(task_of(se)))
-@@ -5404,6 +5454,11 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
- clear_buddies(cfs_rq, se);
-
- update_entity_lag(cfs_rq, se);
-+ if (sched_feat(PLACE_REL_DEADLINE) && !sleep) {
-+ se->deadline -= se->vruntime;
-+ se->rel_deadline = 1;
-+ }
-+
- if (se != cfs_rq->curr)
- __dequeue_entity(cfs_rq, se);
- se->on_rq = 0;
-@@ -6855,6 +6910,14 @@ 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);
+@@ -7103,6 +7146,14 @@ static int dequeue_entities(struct rq *rq, struct sched_entity *se, int flags)
+ p = task_of(se);
+ h_nr_running = 1;
+ idle_h_nr_running = task_has_idle_policy(p);
+#ifdef CONFIG_SCHED_BORE
-+ if (task_sleep) {
-+ cfs_rq = cfs_rq_of(se);
-+ if (cfs_rq->curr == se)
-+ update_curr(cfs_rq);
-+ restart_burst(se);
-+ }
++ if (task_sleep) {
++ cfs_rq = cfs_rq_of(se);
++ if (cfs_rq->curr == se)
++ update_curr(cfs_rq);
++ restart_burst(se);
++ }
+#endif // CONFIG_SCHED_BORE
-
- for_each_sched_entity(se) {
- cfs_rq = cfs_rq_of(se);
-@@ -8637,16 +8700,25 @@ static void yield_task_fair(struct rq *rq)
+ } else {
+ cfs_rq = group_cfs_rq(se);
+ slice = cfs_rq_min_slice(cfs_rq);
+@@ -9018,16 +9069,25 @@ static void yield_task_fair(struct rq *rq)
/*
* Are we the only task in the tree?
*/
@@ -926,17 +937,17 @@ index 1d2cbdb162a6..8666269f73b7 100644
/*
* Tell update_rq_clock() that we've just updated,
* so we don't do microscopic update in schedule()
-@@ -12722,6 +12794,9 @@ static void task_fork_fair(struct task_struct *p)
- curr = cfs_rq->curr;
- if (curr)
- update_curr(cfs_rq);
+@@ -13079,6 +13139,9 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued)
+ static void task_fork_fair(struct task_struct *p)
+ {
+ set_task_max_allowed_capacity(p);
+#ifdef CONFIG_SCHED_BORE
-+ update_burst_score(se);
++ update_burst_score(&p->se);
+#endif // CONFIG_SCHED_BORE
- place_entity(cfs_rq, se, ENQUEUE_INITIAL);
- rq_unlock(rq, &rf);
}
-@@ -12834,6 +12909,10 @@ static void attach_task_cfs_rq(struct task_struct *p)
+
+ /*
+@@ -13189,6 +13252,10 @@ static void attach_task_cfs_rq(struct task_struct *p)
static void switched_from_fair(struct rq *rq, struct task_struct *p)
{
@@ -947,26 +958,11 @@ index 1d2cbdb162a6..8666269f73b7 100644
detach_task_cfs_rq(p);
}
-diff --git a/kernel/sched/features.h b/kernel/sched/features.h
-index 143f55df890b..e97b7b68bdd3 100644
---- a/kernel/sched/features.h
-+++ b/kernel/sched/features.h
-@@ -6,6 +6,10 @@
- */
- SCHED_FEAT(PLACE_LAG, true)
- SCHED_FEAT(PLACE_DEADLINE_INITIAL, true)
-+/*
-+ * Preserve relative virtual deadline on 'migration'.
-+ */
-+SCHED_FEAT(PLACE_REL_DEADLINE, true)
- SCHED_FEAT(RUN_TO_PARITY, true)
-
- /*
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
-index 4c36cc680361..2c7d3eb3b172 100644
+index c03b3d7b320e..bbe2f77aa42d 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
-@@ -1984,7 +1984,11 @@ static inline void update_sched_domain_debugfs(void) { }
+@@ -2075,7 +2075,11 @@ static inline void update_sched_domain_debugfs(void) { }
static inline void dirty_sched_domain_sysctl(int cpu) { }
#endif
@@ -978,7 +974,7 @@ index 4c36cc680361..2c7d3eb3b172 100644
static inline const struct cpumask *task_user_cpus(struct task_struct *p)
{
-@@ -2600,7 +2604,12 @@ extern void wakeup_preempt(struct rq *rq, struct task_struct *p, int flags);
+@@ -2825,7 +2829,12 @@ extern void wakeup_preempt(struct rq *rq, struct task_struct *p, int flags);
extern const_debug unsigned int sysctl_sched_nr_migrate;
extern const_debug unsigned int sysctl_sched_migration_cost;
diff --git a/packages/l/linux-current/files/patches/performance/zen/0001-ZEN-INTERACTIVE-Tune-ondemand-governor-for-interacti.patch b/packages/l/linux-current/files/patches/performance/zen/0001-ZEN-INTERACTIVE-Tune-ondemand-governor-for-interacti.patch
new file mode 100644
index 00000000000..0deed79299b
--- /dev/null
+++ b/packages/l/linux-current/files/patches/performance/zen/0001-ZEN-INTERACTIVE-Tune-ondemand-governor-for-interacti.patch
@@ -0,0 +1,72 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Jan Alexander Steffens (heftig)"
+Date: Mon, 27 Jan 2020 18:27:16 +0100
+Subject: [PATCH] ZEN: INTERACTIVE: Tune ondemand governor for interactivity
+
+4.10:
+During some personal testing with the Dolphin emulator, MuQSS has
+serious problems scaling its frequencies causing poor performance where
+boosting the CPU frequencies would have fixed them. Reducing the
+up_threshold to 45 with MuQSS appears to fix the issue, letting the
+introduction to "Star Wars: Rogue Leader" run at 100% speed versus about
+80% on my test system.
+
+Also, lets refactor the definitions and include some indentation to help
+the reader discern what the scope of all the macros are.
+
+5.4:
+On the last custom kernel benchmark from Phoronix with Xanmod, Michael
+configured all the kernels to run using ondemand instead of the kernel's
+[default selection][1]. This reminded me that another option outside of
+the kernels control is the user's choice to change the cpufreq governor,
+for better or for worse.
+
+In Liquorix, performance is the default governor whether you're running
+acpi-cpufreq or intel-pstate. I expect laptop users to install TLP or
+LMT to control the power balance on their system, especially when
+they're plugged in or on battery. However, it's pretty clear to me a
+lot of people would choose ondemand over performance since it's not
+obvious it has huge performance ramifications with MuQSS, and ondemand
+otherwise is "good enough" for most people.
+
+Lets codify lower up thresholds for MuQSS to more closely synergize with
+its aggressive thread migration behavior. This way when ondemand is
+configured, you get sort of a "performance-lite" type of result but with
+the power savings you expect when leaving the running system idle.
+
+[1]: https://www.phoronix.com/scan.php?page=article&item=xanmod-2020-kernel
+
+5.14:
+Although CFS and similar schedulers (BMQ, PDS, and CacULE), reuse a lot
+more of mainline scheduling and do a good job of pinning single threaded
+tasks to their respective core, there's still applications that
+confusingly run steady near 50% and benefit from going full speed or
+turbo when they need to run (emulators for more recent consoles come to
+mind).
+
+Drop the up threshold for all non-MuQSS schedulers from 80/95 to 55/60.
+
+5.15:
+Remove MuQSS cpufreq configuration.
+---
+ drivers/cpufreq/cpufreq_ondemand.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
+index a7c38b8b3e78..1c8a7165f0dd 100644
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -18,10 +18,10 @@
+ #include "cpufreq_ondemand.h"
+
+ /* On-demand governor macros */
+-#define DEF_FREQUENCY_UP_THRESHOLD (80)
+-#define DEF_SAMPLING_DOWN_FACTOR (1)
++#define DEF_FREQUENCY_UP_THRESHOLD (55)
++#define DEF_SAMPLING_DOWN_FACTOR (5)
+ #define MAX_SAMPLING_DOWN_FACTOR (100000)
+-#define MICRO_FREQUENCY_UP_THRESHOLD (95)
++#define MICRO_FREQUENCY_UP_THRESHOLD (60)
+ #define MIN_FREQUENCY_UP_THRESHOLD (1)
+ #define MAX_FREQUENCY_UP_THRESHOLD (100)
+
diff --git a/packages/l/linux-current/files/patches/performance/zen/0004-ZEN-INTERACTIVE-Tune-mgLRU-to-protect-cache-used-in-.patch b/packages/l/linux-current/files/patches/performance/zen/0004-ZEN-INTERACTIVE-Tune-mgLRU-to-protect-cache-used-in-.patch
deleted file mode 100644
index 61171146679..00000000000
--- a/packages/l/linux-current/files/patches/performance/zen/0004-ZEN-INTERACTIVE-Tune-mgLRU-to-protect-cache-used-in-.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Steven Barrett
-Date: Wed, 11 Aug 2021 18:47:46 -0500
-Subject: [PATCH 04/14] ZEN: INTERACTIVE: Tune mgLRU to protect cache used in
- the last second
-
-Although not identical to the le9 patches that protect a byte-amount of
-cache through tunables, multigenerational LRU now supports protecting
-cache accessed in the last X milliseconds.
-
-In #218, Yu recommends starting with 1000ms and tuning as needed. This
-looks like a safe default and turning on this feature should help users
-that don't know they need it.
----
- mm/vmscan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mm/vmscan.c b/mm/vmscan.c
-index 1de8c68d75cc..9d8be574e622 100644
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3968,7 +3968,7 @@ static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc
- }
-
- /* to protect the working set of the last N jiffies */
--static unsigned long lru_gen_min_ttl __read_mostly;
-+static unsigned long lru_gen_min_ttl __read_mostly = HZ;
-
- static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
- {
diff --git a/packages/l/linux-current/files/patches/performance/zen/0013-ZEN-INTERACTIVE-mm-Disable-proactive-compaction-by-d.patch b/packages/l/linux-current/files/patches/performance/zen/0013-ZEN-INTERACTIVE-mm-Disable-proactive-compaction-by-d.patch
deleted file mode 100644
index 8c7551cd72d..00000000000
--- a/packages/l/linux-current/files/patches/performance/zen/0013-ZEN-INTERACTIVE-mm-Disable-proactive-compaction-by-d.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Sultan Alsawaf
-Date: Sat, 24 Oct 2020 22:17:49 -0700
-Subject: [PATCH 13/14] ZEN: INTERACTIVE: mm: Disable proactive compaction by
- default
-
-On-demand compaction works fine assuming that you don't have a need to
-spam the page allocator nonstop for large order page allocations.
-
-Signed-off-by: Sultan Alsawaf
----
- mm/compaction.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mm/compaction.c b/mm/compaction.c
-index eb95e9b435d0..4dc85a35b4eb 100644
---- a/mm/compaction.c
-+++ b/mm/compaction.c
-@@ -1950,7 +1950,7 @@ static int sysctl_compact_unevictable_allowed __read_mostly = CONFIG_COMPACT_UNE
- * aggressively the kernel should compact memory in the
- * background. It takes values in the range [0, 100].
- */
--static unsigned int __read_mostly sysctl_compaction_proactiveness = 20;
-+static unsigned int __read_mostly sysctl_compaction_proactiveness;
- static int sysctl_extfrag_threshold = 500;
- static int __read_mostly sysctl_compact_memory;
-
diff --git a/packages/l/linux-current/files/series b/packages/l/linux-current/files/series
index 4b6cac10f3f..3df3b1dbe4c 100644
--- a/packages/l/linux-current/files/series
+++ b/packages/l/linux-current/files/series
@@ -1,5 +1,4 @@
patches/build/0001-Make-compiler-calls-ccache-friendly.patch
-patches/build/0001-solus-Don-t-automatically-compress-modules.patch
patches/build/0001-Disable-setlocalversion-from-running.patch
patches/build/0001-Solus-Add-initrd-folders-for-firmware-detection.patch
patches/hardware/0001-Add-Logitech-C310.patch
@@ -9,24 +8,33 @@ patches/hardware/0001-Add-OpenRGB-patches.patch
patches/hardware/0001-drm-amdgpu-enable-SI-and-CIK-support-by-default.patch
patches/hardware/0001-drivers-firmware-skip-simpledrm-if-nvidia-drm.modese.patch
patches/hardware/0001-set-ds-controller-bluetooth-pollrate-to-1-ms.patch
-patches/hardware/asus/0001-Fix-ROG-ALLY-X-audio.patch
-patches/hardware/asus/0002-platform-x86-asus-wmi-add-support-for-vivobook-fan-p.patch
-patches/hardware/asus/0003-hid-asus-use-hid-for-brightness-control-on-keyboard.patch
-patches/hardware/asus/0004-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch
-patches/hardware/asus/0005-platform-x86-asus-wmi-add-debug-print-in-more-key-pl.patch
-patches/hardware/asus/0006-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch
-patches/hardware/asus/0007-acpi-x86-s2idle-add-support-for-screen-off-and-scree.patch
-patches/hardware/asus/0008-drm-Notify-the-suspend-core-when-displays-are-change.patch
-patches/hardware/asus/0009-acpi-x86-s2idle-Move-screen-off-on-code-into-dedicat.patch
-patches/hardware/asus/0010-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch
-patches/hardware/asus/0011-platform-x86-asus-armoury-move-existing-tunings-to-a.patch
-patches/hardware/asus/0012-platform-x86-asus-armoury-add-dgpu-tgp-control.patch
-patches/hardware/asus/0013-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch
-patches/hardware/asus/0014-platform-x86-asus-armoury-add-core-count-control.patch
-patches/hardware/asus/0015-platform-x86-asus-wmi-deprecate-bios-features.patch
-patches/hardware/asus/0016-hid-asus-ally-Add-full-gamepad-support.patch
-patches/hardware/asus/0017-ACPI-PM-Quirk-ASUS-ROG-M16-to-default-to-S3-sleep.patch
-patches/hardware/asus/0018-Bluetooth-btusb-Add-2-USB-HW-IDs-for-MT7925-0xe118-e.patch
+patches/hardware/asus/0001-Input-xpad-add-support-for-ASUS-ROG-RAIKIRI-PRO.patch
+patches/hardware/asus/0002-platform-x86-asus-wmi-don-t-fail-if-platform_profile.patch
+patches/hardware/asus/0003-platform-x86-asus-wmi-Refactor-Ally-suspend-resume.patch
+patches/hardware/asus/0004-platform-x86-asus-wmi-export-symbols-used-for-read-w.patch
+patches/hardware/asus/0005-hid-asus-Add-MODULE_IMPORT_NS-ASUS_WMI.patch
+patches/hardware/asus/0006-platform-x86-asus-armoury-move-existing-tunings-to-a.patch
+patches/hardware/asus/0007-platform-x86-asus-armoury-add-panel_hd_mode-attribut.patch
+patches/hardware/asus/0008-platform-x86-asus-armoury-add-the-ppt_-and-nv_-tunin.patch
+patches/hardware/asus/0009-platform-x86-asus-armoury-add-dgpu-tgp-control.patch
+patches/hardware/asus/0010-platform-x86-asus-armoury-add-apu-mem-control-suppor.patch
+patches/hardware/asus/0011-platform-x86-asus-armoury-add-core-count-control.patch
+patches/hardware/asus/0012-platform-x86-asus-wmi-deprecate-bios-features.patch
+patches/hardware/asus/0013-ALSA-hda-realtek-fixup-ASUS-GA605W.patch
+patches/hardware/asus/0014-hid-asus-ally-Add-joystick-LED-ring-support.patch
+patches/hardware/asus/0015-hid-asus-ally-initial-Ally-X-gamepad.patch
+patches/hardware/asus/0016-hid-asus-ally-initial-gamepad-configuration.patch
+patches/hardware/asus/0017-hid-asus-ally-add-button-remap-attributes.patch
+patches/hardware/asus/0018-hid-asus-ally-add-gamepad-mode-selection.patch
+patches/hardware/asus/0019-hid-asus-ally-Turbo-settings-for-buttons.patch
+patches/hardware/asus/0020-hid-asus-ally-add-vibration-intensity-settings.patch
+patches/hardware/asus/0021-hid-asus-ally-add-JS-deadzones.patch
+patches/hardware/asus/0022-hid-asus-ally-add-trigger-deadzones.patch
+patches/hardware/asus/0023-hid-asus-ally-add-anti-deadzones.patch
+patches/hardware/asus/0024-hid-asus-ally-add-JS-response-curves.patch
+patches/hardware/asus/0025-hid-asus-ally-add-calibrations-wip.patch
+patches/hardware/asus/0026-debug-by-default.patch
+patches/hardware/asus/0027-Tmp-add-GA605W-H7606W-to-AMD-PMF-quirks.patch
patches/hardware/surface/0001-Revert-efi-x86-Set-the-PE-COFF-header-s-NX-compat-fl.patch
patches/hardware/surface/0002-PM-hibernate-Add-a-lockdown_hibernate-parameter.patch
patches/hardware/surface/0003-surface3-oemb-add-DMI-matches-for-Surface-3-with-bro.patch
@@ -39,32 +47,29 @@ patches/hardware/surface/0009-iommu-Use-IOMMU-passthrough-mode-for-IPTS.patch
patches/hardware/surface/0010-hid-Add-support-for-Intel-Precise-Touch-and-Stylus.patch
patches/hardware/surface/0011-iommu-intel-Disable-source-id-verification-for-ITHC.patch
patches/hardware/surface/0012-hid-Add-support-for-Intel-Touch-Host-Controller.patch
-patches/hardware/surface/0013-hwmon-Add-thermal-sensor-driver-for-Surface-Aggregat.patch
-patches/hardware/surface/0014-hwmon-surface_temp-Add-support-for-sensor-names.patch
-patches/hardware/surface/0015-i2c-acpi-Implement-RawBytes-read-access.patch
-patches/hardware/surface/0016-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch
-patches/hardware/surface/0017-Input-soc_button_array-support-AMD-variant-Surface-d.patch
-patches/hardware/surface/0018-platform-surface-surfacepro3_button-don-t-load-on-am.patch
-patches/hardware/surface/0019-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch
-patches/hardware/surface/0020-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch
-patches/hardware/surface/0021-hid-multitouch-Add-support-for-surface-pro-type-cove.patch
-patches/hardware/surface/0022-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch
-patches/hardware/surface/0023-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch
-patches/hardware/surface/0024-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch
-patches/hardware/surface/0025-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch
-patches/hardware/surface/0026-platform-x86-int3472-Enable-I2c-daisy-chain.patch
-patches/hardware/surface/0027-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch
-patches/hardware/surface/0028-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch
-patches/hardware/surface/0029-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch
-patches/hardware/surface/0030-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch
-patches/hardware/surface/0031-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch
-patches/hardware/surface/0032-leds-tps68470-Add-LED-control-for-tps68470.patch
-patches/hardware/surface/0033-media-staging-ipu3-imgu-Fix-multiple-calls-of-s_stre.patch
-patches/hardware/surface/0034-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch
-patches/hardware/surface/0035-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch
-patches/hardware/surface/0036-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch
-patches/hardware/surface/0037-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch
-patches/performance/0001-linux6.11.y-bore5.7.3.patch
+patches/hardware/surface/0013-i2c-acpi-Implement-RawBytes-read-access.patch
+patches/hardware/surface/0014-platform-surface-Add-driver-for-Surface-Book-1-dGPU-.patch
+patches/hardware/surface/0015-Input-soc_button_array-support-AMD-variant-Surface-d.patch
+patches/hardware/surface/0016-platform-surface-surfacepro3_button-don-t-load-on-am.patch
+patches/hardware/surface/0017-USB-quirks-Add-USB_QUIRK_DELAY_INIT-for-Surface-Go-3.patch
+patches/hardware/surface/0018-hid-multitouch-Turn-off-Type-Cover-keyboard-backligh.patch
+patches/hardware/surface/0019-hid-multitouch-Add-support-for-surface-pro-type-cove.patch
+patches/hardware/surface/0020-PCI-Add-quirk-to-prevent-calling-shutdown-mehtod.patch
+patches/hardware/surface/0021-platform-surface-gpe-Add-support-for-Surface-Pro-9.patch
+patches/hardware/surface/0022-ACPI-delay-enumeration-of-devices-with-a-_DEP-pointi.patch
+patches/hardware/surface/0023-iommu-intel-ipu-use-IOMMU-passthrough-mode-for-Intel.patch
+patches/hardware/surface/0024-platform-x86-int3472-Enable-I2c-daisy-chain.patch
+patches/hardware/surface/0025-platform-x86-int3472-Remap-reset-GPIO-for-INT347E.patch
+patches/hardware/surface/0026-media-i2c-Clarify-that-gain-is-Analogue-gain-in-OV72.patch
+patches/hardware/surface/0027-media-v4l2-core-Acquire-privacy-led-in-v4l2_async_re.patch
+patches/hardware/surface/0028-platform-x86-int3472-Add-MFD-cell-for-tps68470-LED.patch
+patches/hardware/surface/0029-include-mfd-tps68470-Add-masks-for-LEDA-and-LEDB.patch
+patches/hardware/surface/0030-leds-tps68470-Add-LED-control-for-tps68470.patch
+patches/hardware/surface/0031-media-i2c-dw9719-fix-probe-error-on-surface-go-2.patch
+patches/hardware/surface/0032-ACPI-Add-quirk-for-Surface-Laptop-4-AMD-missing-irq-.patch
+patches/hardware/surface/0033-ACPI-Add-AMD-13-Surface-Laptop-4-model-to-irq-7-over.patch
+patches/hardware/surface/0034-acpi-allow-usage-of-acpi_tad-on-HW-reduced-platforms.patch
+patches/performance/0001-linux6.12.y-bore5.7.13.patch
patches/performance/0001-tcp-bbr3-initial-import.patch
patches/performance/0001-NT-synchronization-primitive-driver.patch
patches/performance/0001-futex-Add-entry-point-for-FUTEX_WAIT_MULTIPLE-opcode.patch
@@ -72,7 +77,6 @@ patches/performance/0001-Add-kernel-arg-to-enable-amdgpu-overdrive.patch
patches/performance/zen/0001-ZEN-Initialize-ata-before-graphics.patch
patches/performance/zen/0002-ZEN-Input-evdev-use-call_rcu-when-detaching-client.patch
patches/performance/zen/0003-ZEN-mm-Stop-kswapd-early-when-nothing-s-waiting-for-.patch
-patches/performance/zen/0004-ZEN-INTERACTIVE-Tune-mgLRU-to-protect-cache-used-in-.patch
patches/performance/zen/0005-ZEN-INTERACTIVE-Use-BFQ-as-the-elevator-for-SQ-devic.patch
patches/performance/zen/0006-ZEN-INTERACTIVE-Use-Kyber-as-the-elevator-for-MQ-dev.patch
patches/performance/zen/0007-ZEN-INTERACTIVE-dm-crypt-Disable-workqueues-for-cryp.patch
@@ -81,6 +85,6 @@ patches/performance/zen/0009-ZEN-INTERACTIVE-mm-Disable-watermark-boosting-by-de
patches/performance/zen/0010-ZEN-INTERACTIVE-mm-swap-Disable-swap-in-readahead.patch
patches/performance/zen/0011-ZEN-INTERACTIVE-mm-Lower-the-non-hugetlbpage-pageblo.patch
patches/performance/zen/0012-ZEN-INTERACTIVE-mm-Disable-unevictable-compaction.patch
-patches/performance/zen/0013-ZEN-INTERACTIVE-mm-Disable-proactive-compaction-by-d.patch
+patches/performance/zen/0001-ZEN-INTERACTIVE-Tune-ondemand-governor-for-interacti.patch
patches/performance/zen/0014-ZEN-drm-amdgpu-pm-Allow-override-of-min_power_limit-.patch
patches/security/0001-Add-sysctl-and-CONFIG-to-disallow-unprivileged-CLONE.patch
diff --git a/packages/l/linux-current/package.yml b/packages/l/linux-current/package.yml
index b2d7a4c5b36..bd4bbf3c1f1 100644
--- a/packages/l/linux-current/package.yml
+++ b/packages/l/linux-current/package.yml
@@ -1,8 +1,8 @@
name : linux-current
-version : 6.11.10
-release : 310
+version : 6.12.5
+release : 311
source :
- - https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.11.10.tar.xz : 4bc184915290629d61f935aa1eb1b6e711b8e47d8f289a39f0d584ecbdb4fe77
+ - https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.12.5.tar.xz : 39207fce1ce42838e085261bae0af5ce4a0843aa777cfc0f5c49bc7729602bcd
license : GPL-2.0-only
component :
- kernel.image
diff --git a/packages/l/linux-current/pspec_x86_64.xml b/packages/l/linux-current/pspec_x86_64.xml
index 70b4945ba25..dfc2464d6f6 100644
--- a/packages/l/linux-current/pspec_x86_64.xml
+++ b/packages/l/linux-current/pspec_x86_64.xml
@@ -18,7700 +18,7690 @@