diff -pruN 3.4.0+dfsg-1/.bumpversion.cfg 3.5.1+dfsg-2/.bumpversion.cfg
--- 3.4.0+dfsg-1/.bumpversion.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/.bumpversion.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 3.4.0
+current_version = 3.5.1
 
 [bumpversion:file:pylib/openrazer/client/__init__.py]
 
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/daemon.py 3.5.1+dfsg-2/daemon/openrazer_daemon/daemon.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/daemon.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/daemon.py	2022-12-04 11:49:31.000000000 +0000
@@ -5,7 +5,7 @@ Daemon class
 
 This class is the main core of the daemon, this serves a basic dbus module to control the main bit of the daemon
 """
-__version__ = '3.4.0'
+__version__ = '3.5.1'
 
 import configparser
 import logging
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/dbus_services/dbus_methods/argb_controller.py 3.5.1+dfsg-2/daemon/openrazer_daemon/dbus_services/dbus_methods/argb_controller.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/dbus_services/dbus_methods/argb_controller.py	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/dbus_services/dbus_methods/argb_controller.py	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from openrazer_daemon.dbus_services import endpoint
+
+
+@endpoint('razer.device.lighting.channel', 'getNumChannels', out_sig='q')
+def get_num_channels(self):
+    return self.NUM_CHANNELS
+
+
+def _get_channel_brightness(self, channel):
+    driver_path = self.get_driver_path(channel + '_led_brightness')
+    with open(driver_path, 'r') as driver_file:
+        return float(driver_file.read().strip()) / (255.0 / 100.0)
+
+
+@endpoint('razer.device.lighting.channel', 'getChannelBrightness', in_sig='q', out_sig='d')
+def get_channel_brightness(self, channel):
+    """
+    Get the channel brightness
+
+    :param channel: Channel number to get the brightness of
+    :type channel: int
+
+    :return: Brightness
+    :rtype: float
+    """
+    channel_name = 'channel{}'.format(channel)
+    self.logger.debug("DBus call get_{}_brightness".format(channel_name))
+    return _get_channel_brightness(self, channel_name)
+
+
+def _set_channel_brightness(self, channel, brightness):
+    driver_path = self.get_driver_path(channel + '_led_brightness')
+
+    self.method_args['brightness'] = brightness
+
+    if brightness > 100:
+        brightness = 100
+    elif brightness < 0:
+        brightness = 0
+
+    self.set_persistence(channel, "brightness", int(brightness))
+
+    brightness = int(round(brightness * (255.0 / 100.0)))
+
+    with open(driver_path, 'w') as driver_file:
+        driver_file.write(str(brightness))
+
+    # Notify others
+    self.send_effect_event('setBrightness', brightness)
+
+
+@endpoint('razer.device.lighting.channel', 'setChannelBrightness', in_sig='qd')
+def set_channel_brightness(self, channel, brightness):
+    """
+    Set the device's brightness
+
+    :param channel: Channel
+    :type channel: int
+
+    :param brightness: Brightness
+    :type brightness: int
+    """
+    channel_name = 'channel{}'.format(channel)
+    self.logger.debug("DBus call set_{}_brightness".format(channel_name))
+    _set_channel_brightness(self, channel_name, brightness)
+
+
+def _get_channel_size(self, channel):
+    driver_path = self.get_driver_path(channel + '_size')
+    with open(driver_path, 'r') as driver_file:
+        return int(driver_file.read().strip())
+
+
+@endpoint('razer.device.lighting.channel', 'getChannelSize', in_sig='q', out_sig='i')
+def get_channel_size(self, channel):
+    """
+    Get the device's size
+
+    :param channel: Channel
+    :type channel: int
+
+    :return: Size
+    :rtype: float
+    """
+    channel_name = 'channel{}'.format(channel)
+    self.logger.debug("DBus call get_{}_size".format(channel_name))
+    return _get_channel_size(self, channel_name)
+
+
+def _set_channel_size(self, channel, size):
+    driver_path = self.get_driver_path(channel + '_size')
+
+    self.method_args['size'] = size
+
+    if size > 255:
+        size = 255
+    elif size < 0:
+        size = 0
+
+    self.set_persistence(channel, "size", int(size))
+
+    with open(driver_path, 'w') as driver_file:
+        driver_file.write(str(size))
+
+    # Notify others
+    self.send_effect_event('setSize', size)
+
+
+@endpoint('razer.device.lighting.channel', 'setChannelSize', in_sig='qi')
+def set_channel_size(self, channel, size):
+    """
+    Set the device's size
+    :param channel: Channel
+    :type channel: int
+
+    :param size: Size
+    :type size: int
+    """
+    channel_name = 'channel{}'.format(channel)
+
+    self.logger.debug("DBus call set_{}_size".format(channel_name))
+    _set_channel_size(self, channel_name, size)
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/dbus_services/dbus_methods/__init__.py 3.5.1+dfsg-2/daemon/openrazer_daemon/dbus_services/dbus_methods/__init__.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/dbus_services/dbus_methods/__init__.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/dbus_services/dbus_methods/__init__.py	2022-12-04 11:49:31.000000000 +0000
@@ -19,3 +19,4 @@ from openrazer_daemon.dbus_services.dbus
 from openrazer_daemon.dbus_services.dbus_methods.accessory import *
 from openrazer_daemon.dbus_services.dbus_methods.charging_pad_chroma import *
 from openrazer_daemon.dbus_services.dbus_methods.mouse_scroll_wheel import *
+from openrazer_daemon.dbus_services.dbus_methods.argb_controller import *
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/accessory.py 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/accessory.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/accessory.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/accessory.py	2022-12-04 11:49:31.000000000 +0000
@@ -26,6 +26,28 @@ class RazerChromaMugHolder(_RazerDeviceB
     DEVICE_IMAGE = "https://assets2.razerzone.com/images/mug-holder/e64e507b73e61c44789d996065fd9645-1500x1000mug_01.jpg"
 
 
+class RazerChromaARGB(_RazerDeviceBrightnessSuspend):
+    """
+    Class for the Razer Chroma Addressable RGB Controller
+    """
+    USB_VID = 0x1532
+    USB_PID = 0x0F1F
+    HAS_MATRIX = True
+    MATRIX_DIMS = [6, 80]
+    NUM_CHANNELS = 6
+    WAVE_DIRS = (1, 2)
+    METHODS = ['get_device_type_accessory',
+               'set_static_effect', 'set_wave_effect', 'set_spectrum_effect',
+               'set_none_effect', 'set_breath_random_effect',
+               'set_breath_single_effect', 'set_breath_dual_effect',
+               'set_custom_effect', 'set_key_row',
+               'get_num_channels',
+               'get_channel_brightness', 'set_channel_brightness',
+               'get_channel_size', 'set_channel_size']
+
+    DEVICE_IMAGE = "https://dl.razerzone.com/src/3903-1-EN-v1.png"
+
+
 class RazerChromaHDK(_RazerDeviceBrightnessSuspend):
     """
     Class for the Razer Chroma Hardware Development Kit (HDK)
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/core.py 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/core.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/core.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/core.py	2022-12-04 11:49:31.000000000 +0000
@@ -18,5 +18,5 @@ class RazerCore(__RazerDeviceBrightnessS
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/684/684_razer_core.png"
 
     METHODS = ['set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
-               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
+               'set_reactive_effect', 'trigger_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
                'set_custom_effect', 'set_key_row', 'get_device_type_core']
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/device_base.py 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/device_base.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/device_base.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/device_base.py	2022-12-04 11:49:31.000000000 +0000
@@ -39,7 +39,7 @@ class RazerDevice(DBusService):
 
     WAVE_DIRS = (1, 2)
 
-    ZONES = ('backlight', 'logo', 'scroll', 'left', 'right', 'charging', 'fast_charging', 'fully_charged')
+    ZONES = ('backlight', 'logo', 'scroll', 'left', 'right', 'charging', 'fast_charging', 'fully_charged', 'channel1', 'channel2', 'channel3', 'channel4', 'channel5', 'channel6')
 
     DEVICE_IMAGE = None
 
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/keyboards.py 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/keyboards.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/keyboards.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/keyboards.py	2022-12-04 11:49:31.000000000 +0000
@@ -147,7 +147,7 @@ class RazerTartarusChroma(_RazerDeviceBr
     USB_PID = 0x0208
     DEDICATED_MACRO_KEYS = True
     METHODS = ['get_device_type_keypad', 'set_breath_random_effect', 'set_breath_single_effect',
-               'set_breath_dual_effect', 'set_static_effect', 'set_spectrum_effect', 'keypad_get_profile_led_red', 'keypad_set_profile_led_red', 'keypad_get_profile_led_green',
+               'set_breath_dual_effect', 'set_none_effect', 'set_static_effect', 'set_spectrum_effect', 'keypad_get_profile_led_red', 'keypad_set_profile_led_red', 'keypad_get_profile_led_green',
                'keypad_set_profile_led_green', 'keypad_get_profile_led_blue', 'keypad_set_profile_led_blue', 'get_macros', 'delete_macro', 'add_macro', 'keypad_get_mode_modifier', 'keypad_set_mode_modifier']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/598/598_tartarus_chroma.png"
@@ -192,7 +192,8 @@ class RazerTartarusV2(_RippleKeyboard):
                'keypad_get_profile_led_red', 'keypad_set_profile_led_red',
                'keypad_get_profile_led_green', 'keypad_set_profile_led_green',
                'keypad_get_profile_led_blue', 'keypad_set_profile_led_blue',
-               'get_macro_effect', 'set_macro_effect', 'get_macros', 'delete_macro', 'add_macro',
+               'get_macro_mode', 'set_macro_mode', 'get_macro_effect', 'set_macro_effect',
+               'get_macros', 'delete_macro', 'add_macro',
                'set_ripple_effect', 'set_ripple_effect_random_colour',
                'get_game_mode', 'set_game_mode',
                'keypad_get_mode_modifier', 'keypad_set_mode_modifier']
@@ -223,8 +224,7 @@ class RazerOrbweaver(_RazerDeviceBrightn
     METHODS = ['get_device_type_keypad',
                'keypad_get_profile_led_red', 'keypad_set_profile_led_red', 'keypad_get_profile_led_green', 'keypad_set_profile_led_green', 'keypad_get_profile_led_blue', 'keypad_set_profile_led_blue',
                'get_macros', 'delete_macro', 'add_macro', 'keypad_get_mode_modifier', 'keypad_set_mode_modifier',
-
-               'bw_set_pulsate', 'bw_set_static']
+               'set_none_effect', 'bw_set_pulsate', 'bw_set_static']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/56/56_orbweaver.png"
 
@@ -258,7 +258,7 @@ class RazerOrbweaverChroma(_RippleKeyboa
     METHODS = ['get_device_type_keypad',
                'set_key_row',
                'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
-               'set_static_effect', 'set_spectrum_effect', 'set_wave_effect', 'set_custom_effect',
+               'set_none_effect', 'set_static_effect', 'set_spectrum_effect', 'set_wave_effect', 'set_custom_effect',
                'keypad_get_profile_led_red', 'keypad_set_profile_led_red',
                'keypad_get_profile_led_green', 'keypad_set_profile_led_green',
                'keypad_get_profile_led_blue', 'keypad_set_profile_led_blue',
@@ -452,7 +452,7 @@ class RazerBlackWidowChromaTournamentEdi
     METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
                'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
                'set_custom_effect', 'set_key_row', 'get_game_mode', 'set_game_mode', 'get_macros', 'delete_macro', 'add_macro',
-
+               'get_macro_mode', 'set_macro_mode', 'get_macro_effect', 'set_macro_effect',
                'set_ripple_effect', 'set_ripple_effect_random_colour']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/571/571_blackwidow_tournament_edition_chroma.png"
@@ -478,6 +478,28 @@ class RazerBlackWidowXChroma(_RippleKeyb
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/716/716_blackwidow_x_chroma.png"
 
 
+class RazerHuntsmanV2Tenkeyless(_RippleKeyboard):
+    """
+    Class for the Razer Huntsman V2 Tenkeyless
+    """
+    EVENT_FILE_REGEX = re.compile(r'.*Razer_Huntsman_V2_Tenkeyless(-if01)?-event-kbd')
+
+    USB_VID = 0x1532
+    USB_PID = 0x026B
+    HAS_MATRIX = True
+    MATRIX_DIMS = [6, 18]
+    POLL_RATES = [125, 250, 500, 1000, 2000, 4000, 8000]
+    METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
+               'set_custom_effect', 'set_key_row', 'get_game_mode', 'set_game_mode', 'get_macro_mode', 'set_macro_mode',
+               'get_macro_effect', 'set_macro_effect', 'get_macros', 'delete_macro', 'add_macro',
+               'get_poll_rate', 'set_poll_rate', 'get_supported_poll_rates', 'get_keyswitch_optimization', 'set_keyswitch_optimization',
+               'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
+               'set_ripple_effect', 'set_ripple_effect_random_colour']
+
+    DEVICE_IMAGE = "https://dl.razerzone.com/src/5638/5638-1-en-v1.png"
+
+
 class RazerHuntsmanV2(_RippleKeyboard):
     """
     Class for the Razer Huntsman V2
@@ -514,6 +536,7 @@ class RazerHuntsmanV2Analog(_RazerDevice
     # TODO Remove get_keyboard_layout once not _RazerDeviceBrightnessSuspend anymore
     METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
                'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
+               'get_macro_mode', 'set_macro_mode', 'get_macro_effect', 'set_macro_effect', 'get_game_mode', 'set_game_mode',
                'set_custom_effect', 'set_key_row', 'get_keyboard_layout']
 
     DEVICE_IMAGE = "https://dl.razerzone.com/src/4023-1-EN-v1.png"
@@ -533,6 +556,7 @@ class RazerHuntsmanMiniAnalog(_RazerDevi
     # TODO Remove get_keyboard_layout once not _RazerDeviceBrightnessSuspend anymore
     METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
                'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
+               'get_macro_mode', 'set_macro_mode', 'get_macro_effect', 'set_macro_effect', 'get_game_mode', 'set_game_mode',
                'set_custom_effect', 'set_key_row', 'get_keyboard_layout']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1689/1689-huntsmanmini.png"
@@ -1029,6 +1053,8 @@ class RazerBlackWidowEssential(_RippleKe
     HAS_MATRIX = True
     MATRIX_DIMS = [6, 22]
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_none_effect',
+               'set_spectrum_effect', 'set_wave_effect', 'set_reactive_effect',
+               'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
                'set_breath_single_effect', 'set_key_row', 'set_custom_effect', 'get_game_mode',
                'set_game_mode', 'get_macro_mode', 'set_macro_mode', 'get_macro_effect',
                'set_macro_effect', 'get_macros', 'delete_macro', 'add_macro']
@@ -1106,6 +1132,26 @@ class RazerDeathStalkerChroma(_RippleKey
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/665/665_deathstalker_chroma.png"
 
 
+class RazerDeathStalkerV2(_RippleKeyboard):
+    """
+    Class for the Razer DeathStalker V2
+    """
+    EVENT_FILE_REGEX = re.compile(r'.*DeathStalker_V2(-if01)?-event-kbd')
+
+    USB_VID = 0x1532
+    USB_PID = 0x0295
+    HAS_MATRIX = True
+    MATRIX_DIMS = [6, 22]
+    METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
+               'set_custom_effect', 'set_key_row', 'get_game_mode', 'set_game_mode', 'get_macro_mode', 'set_macro_mode',
+               'get_macro_effect', 'set_macro_effect', 'get_macros', 'delete_macro', 'add_macro',
+               'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
+               'set_ripple_effect', 'set_ripple_effect_random_colour']
+
+    DEVICE_IMAGE = "https://dl.razerzone.com/src/6118/6118-1-en-v1.png"
+
+
 class RazerBlackWidowChromaOverwatch(_RippleKeyboard):
     """
     Class for the Razer BlackWidow Chroma (Overwatch)
@@ -1246,7 +1292,7 @@ class RazerBlade2018Base(_RippleKeyboard
     USB_VID = 0x1532
     USB_PID = 0x023B
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1418/1418_blade_2018__base.png"
 
@@ -1260,7 +1306,7 @@ class RazerBladeStealth2019(_RippleKeybo
     USB_VID = 0x1532
     USB_PID = 0x0239
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1475/1475_bladestealth13(2019).png"
 
@@ -1274,7 +1320,7 @@ class RazerBladeStealthLate2019(_RippleK
     USB_VID = 0x1532
     USB_PID = 0x024A
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
 
     DEVICE_IMAGE = "https://assets2.razerzone.com/images/blade-stealth-13/shop/stealth-l2p-1.jpg"
 
@@ -1288,7 +1334,7 @@ class RazerBladeStealthEarly2020(_Ripple
     USB_VID = 0x1532
     USB_PID = 0x0252
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
 
     DEVICE_IMAGE = "https://assets2.razerzone.com/images/blade-stealth-13/shop/sl25p-fhd-4.jpg"
 
@@ -1302,7 +1348,7 @@ class RazerBladeStealthLate2020(_RippleK
     USB_VID = 0x1532
     USB_PID = 0x0259
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
 
     DEVICE_IMAGE = "https://assets2.razerzone.com/images/blade-stealth-13/shop/sl25p-fhd-4.jpg"
 
@@ -1316,7 +1362,7 @@ class RazerBook2020(_RippleKeyboard):
     USB_VID = 0x1532
     USB_PID = 0x026A
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1743/razerbook132020.png"
 
@@ -1368,7 +1414,7 @@ class RazerBlade2019Base(_RippleKeyboard
     USB_VID = 0x1532
     USB_PID = 0x0246
     METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1518/1518_blade15_mid2019-base.png"
 
@@ -1381,13 +1427,9 @@ class RazerBladeEarly2020Base(_RippleKey
 
     USB_VID = 0x1532
     USB_PID = 0x0255
-    HAS_MATRIX = True
-    MATRIX_DIMS = [1, 16]
-    METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
+    METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
                'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect',
-               'set_breath_dual_effect', 'set_custom_effect', 'set_key_row',
-               'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
-               'set_ripple_effect', 'set_ripple_effect_random_colour']
+               'set_breath_dual_effect']
 
     DEVICE_IMAGE = "https://assets2.razerzone.com/images/blade-15/blade-15-base-model-spec-image-v2.png"
 
@@ -1457,7 +1499,8 @@ class RazerBladePro2019(_RippleKeyboard)
     USB_PID = 0x0234
     HAS_MATRIX = True
     MATRIX_DIMS = [6, 16]
-    METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
+    METHODS = ['get_device_type_keyboard', 'get_logo_active', 'set_logo_active',
+               'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
                'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect',
                'set_breath_dual_effect', 'set_custom_effect', 'set_key_row',
                'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
@@ -1601,22 +1644,37 @@ class RazerBlade15AdvancedEarly2021(_Rip
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1761/blade-15-advanced-2021-rz09-0367x.png"
 
 
-class RazerBladeEarly2021Base(_RippleKeyboard):
+class RazerBlade17ProEarly2021(_RippleKeyboard):
     """
-    Class for the Razer Blade Base (Early 2021)
+    Class for the Razer Blade 17 Pro (Early 2021)
     """
     EVENT_FILE_REGEX = re.compile(r'.*Razer_Blade(-if01)?-event-kbd')
 
     USB_VID = 0x1532
-    USB_PID = 0x026F
+    USB_PID = 0x026E
     HAS_MATRIX = True
-    MATRIX_DIMS = [1, 16]
-    METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
+    MATRIX_DIMS = [6, 16]
+    METHODS = ['get_device_type_keyboard', 'get_logo_active', 'set_logo_active', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
                'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect',
                'set_breath_dual_effect', 'set_custom_effect', 'set_key_row',
                'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
                'set_ripple_effect', 'set_ripple_effect_random_colour']
 
+    DEVICE_IMAGE = "https://dl.razerzone.com/src/4025-16-EN-v1.png"
+
+
+class RazerBladeEarly2021Base(_RippleKeyboard):
+    """
+    Class for the Razer Blade Base (Early 2021)
+    """
+    EVENT_FILE_REGEX = re.compile(r'.*Razer_Blade(-if01)?-event-kbd')
+
+    USB_VID = 0x1532
+    USB_PID = 0x026F
+    METHODS = ['get_device_type_keyboard', 'set_static_effect', 'set_spectrum_effect',
+               'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect',
+               'set_breath_dual_effect']
+
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1756/blade-15-base-2021-rz09-0369x.png"
 
 
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/mouse_mat.py 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/mouse_mat.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/mouse_mat.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/mouse_mat.py	2022-12-04 11:49:31.000000000 +0000
@@ -31,7 +31,7 @@ class RazerFireflyV2(__RazerDeviceBright
     MATRIX_DIMS = [1, 19]
     METHODS = ['get_device_type_mousemat', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
                'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
-               'set_custom_effect', 'set_key_row', 'trigger_reactive_effect']
+               'set_custom_effect', 'set_key_row', 'set_reactive_effect', 'trigger_reactive_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1594/1594_firefly_v2.png"
 
@@ -45,7 +45,8 @@ class RazerFireflyHyperflux(__RazerDevic
     HAS_MATRIX = True
     MATRIX_DIMS = [1, 17]
     METHODS = ['get_device_type_mousemat', 'set_static_effect', 'set_spectrum_effect', 'set_key_row', 'set_custom_effect',
-               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect']
+               'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
+               'set_reactive_effect', 'trigger_reactive_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/594/594_firefly_500x500.png"
 
@@ -60,7 +61,7 @@ class RazerGoliathus(__RazerDeviceBright
     MATRIX_DIMS = [1, 1]
     METHODS = ['get_device_type_mousemat', 'set_static_effect', 'set_spectrum_effect',
                'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
-               'set_custom_effect', 'set_key_row']
+               'set_custom_effect', 'set_key_row', 'set_reactive_effect', 'trigger_reactive_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1394/1394_goliathus_chroma.png"
 
@@ -75,6 +76,6 @@ class RazerGoliathusExtended(__RazerDevi
     MATRIX_DIMS = [1, 1]
     METHODS = ['get_device_type_mousemat', 'set_static_effect', 'set_spectrum_effect',
                'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
-               'set_custom_effect', 'set_key_row']
+               'set_custom_effect', 'set_key_row', 'set_reactive_effect', 'trigger_reactive_effect']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1395/1395_goliathusextended.png"
diff -pruN 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/mouse.py 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/mouse.py
--- 3.4.0+dfsg-1/daemon/openrazer_daemon/hardware/mouse.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/openrazer_daemon/hardware/mouse.py	2022-12-04 11:49:31.000000000 +0000
@@ -27,7 +27,7 @@ class RazerViperMini(__RazerDeviceSpecia
     USB_PID = 0x008A
     HAS_MATRIX = True
     MATRIX_DIMS = [1, 1]
-    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
                # Underglow/Logo use LOGO_LED
                'set_logo_static_naga_hex_v2', 'set_logo_spectrum_naga_hex_v2', 'set_logo_none_naga_hex_v2', 'set_logo_reactive_naga_hex_v2',
                'set_logo_breath_random_naga_hex_v2', 'set_logo_breath_single_naga_hex_v2', 'set_logo_breath_dual_naga_hex_v2',
@@ -75,7 +75,7 @@ class RazerLanceheadWirelessWired(__Raze
     HAS_MATRIX = True
     WAVE_DIRS = (1, 2)
     MATRIX_DIMS = [1, 16]
-    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness', 'get_scroll_brightness', 'set_scroll_brightness',
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness', 'get_scroll_brightness', 'set_scroll_brightness',
                'get_left_brightness', 'set_left_brightness', 'get_right_brightness', 'set_right_brightness',
                # Battery
                'get_battery', 'is_charging', 'set_idle_time', 'set_low_battery_threshold',
@@ -162,7 +162,7 @@ class RazerLanceheadWired(__RazerDeviceS
     HAS_MATRIX = True
     WAVE_DIRS = (1, 2)
     MATRIX_DIMS = [1, 16]
-    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness', 'get_scroll_brightness', 'set_scroll_brightness',
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness', 'get_scroll_brightness', 'set_scroll_brightness',
                'get_left_brightness', 'set_left_brightness', 'get_right_brightness', 'set_right_brightness',
                # Battery
                'get_battery', 'is_charging', 'set_idle_time', 'set_low_battery_threshold',
@@ -385,7 +385,7 @@ class RazerLanceheadTE(__RazerDeviceSpec
     HAS_MATRIX = True
     WAVE_DIRS = (1, 2)
     MATRIX_DIMS = [1, 16]
-    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness', 'get_scroll_brightness', 'set_scroll_brightness',
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness', 'get_scroll_brightness', 'set_scroll_brightness',
                'get_left_brightness', 'set_left_brightness', 'get_right_brightness', 'set_right_brightness',
                # Logo
                'set_logo_wave', 'set_logo_static_naga_hex_v2', 'set_logo_spectrum_naga_hex_v2', 'set_logo_none_naga_hex_v2', 'set_logo_reactive_naga_hex_v2', 'set_logo_breath_random_naga_hex_v2', 'set_logo_breath_single_naga_hex_v2', 'set_logo_breath_dual_naga_hex_v2',
@@ -611,7 +611,9 @@ class RazerOrochiWired(__RazerDeviceBrig
     USB_PID = 0x0048
     METHODS = ['get_device_type_mouse',
                'set_static_effect', 'set_spectrum_effect', 'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect',
-               'set_breath_single_effect', 'set_breath_dual_effect', 'set_idle_time', 'set_low_battery_threshold', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'set_scroll_active', 'get_scroll_active']
+               'set_breath_single_effect', 'set_breath_dual_effect', 'set_idle_time', 'set_low_battery_threshold',
+               'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'set_scroll_active', 'get_scroll_active',
+               'get_poll_rate', 'set_poll_rate']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/612/612_orochi_2015.png"
 
@@ -1663,8 +1665,8 @@ class RazerDeathAdder3500(__RazerDeviceS
     USB_VID = 0x1532
     USB_PID = 0x0054
     METHODS = ['get_device_type_mouse',
-               'get_logo_brightness', 'set_logo_brightness', 'set_logo_static', 'set_logo_pulsate', 'set_logo_blinking',
-               'get_scroll_brightness', 'set_scroll_brightness', 'set_scroll_static', 'set_scroll_pulsate', 'set_scroll_blinking',
+               'get_logo_brightness', 'set_logo_brightness', 'set_logo_active', 'get_logo_active', 'set_logo_static', 'set_logo_pulsate', 'set_logo_blinking',
+               'get_scroll_brightness', 'set_scroll_active', 'get_scroll_active', 'set_scroll_brightness', 'set_scroll_static', 'set_scroll_pulsate', 'set_scroll_blinking',
                'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate']
 
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/561/561_deathadder_classic.png"
@@ -1720,7 +1722,7 @@ class RazerViperUltimateWired(__RazerDev
     USB_PID = 0x007A
     HAS_MATRIX = True
     MATRIX_DIMS = [1, 1]
-    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
                # Battery
                'get_battery', 'is_charging', 'set_idle_time', 'set_low_battery_threshold',
                # Logo
@@ -1795,7 +1797,7 @@ class RazerViper(__RazerDeviceSpecialBri
     USB_PID = 0x0078
     HAS_MATRIX = True
     MATRIX_DIMS = [1, 1]
-    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
                # Logo
                'set_logo_static_naga_hex_v2', 'set_logo_spectrum_naga_hex_v2', 'set_logo_none_naga_hex_v2', 'set_logo_reactive_naga_hex_v2',
                'set_logo_breath_random_naga_hex_v2', 'set_logo_breath_single_naga_hex_v2', 'set_logo_breath_dual_naga_hex_v2',
@@ -2053,7 +2055,7 @@ class RazerNagaLeftHanded2020(__RazerDev
         self.disable_notify = False
 
 
-class RazerNagaProWired(__RazerDeviceSpecialBrightnessSuspend):
+class RazerNagaProWired(__RazerDeviceBrightnessSuspend):
     """
     Class for the Razer Naga Pro (Wired)
     """
@@ -2319,7 +2321,7 @@ class RazerBasiliskUltimateWired(__Razer
                'set_scroll_reactive_naga_hex_v2',
                # Breath
                'set_scroll_breath_random_naga_hex_v2',
-               'set_scroll_breath_random_naga_hex_v2',
+               'set_scroll_breath_single_naga_hex_v2',
                'set_scroll_breath_dual_naga_hex_v2',
                # Static
                'set_scroll_static_naga_hex_v2',
@@ -2530,6 +2532,8 @@ class RazerDeathAdderV2(__RazerDeviceSpe
 
     USB_VID = 0x1532
     USB_PID = 0x0084
+    HAS_MATRIX = True
+    MATRIX_DIMS = [1, 1]
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1612/1612_razerdeathadderv2.png"
 
     DPI_MAX = 20000
@@ -2574,7 +2578,7 @@ class RazerDeathAdderV2ProWired(__RazerD
     USB_PID = 0x007C
     HAS_MATRIX = True
     MATRIX_DIMS = [1, 1]
-    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages', 'get_poll_rate', 'set_poll_rate', 'get_logo_brightness', 'set_logo_brightness',
                # Battery
                'get_battery', 'is_charging', 'set_idle_time', 'set_low_battery_threshold',
                # Logo
@@ -2767,6 +2771,63 @@ class RazerOrochiV2Bluetooth(RazerOrochi
     USB_PID = 0x0095
 
 
+class RazerNagaX(__RazerDeviceSpecialBrightnessSuspend):
+    """
+    Class for the Razer Naga X
+    """
+    USB_VID = 0x1532
+    USB_PID = 0x0096
+    HAS_MATRIX = True
+    WAVE_DIRS = (1, 2)
+    MATRIX_DIMS = [1, 2]
+
+    DEDICATED_MACRO_KEYS = True
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy',
+               'get_dpi_stages', 'set_dpi_stages',
+               'get_poll_rate', 'set_poll_rate',
+               # Macros
+               'get_macros', 'delete_macro', 'add_macro',
+               # Scroll wheel
+               'get_scroll_brightness', 'set_scroll_brightness',
+               'set_scroll_wave', 'set_scroll_static_naga_hex_v2', 'set_scroll_spectrum_naga_hex_v2', 'set_scroll_none_naga_hex_v2', 'set_scroll_reactive_naga_hex_v2', 'set_scroll_breath_random_naga_hex_v2', 'set_scroll_breath_single_naga_hex_v2', 'set_scroll_breath_dual_naga_hex_v2',
+               # Left side = thumbgrid
+               'get_left_brightness', 'set_left_brightness',
+               'set_left_wave', 'set_left_static', 'set_left_spectrum', 'set_left_none', 'set_left_reactive', 'set_left_breath_random', 'set_left_breath_single', 'set_left_breath_dual',
+               # Custom frame
+               'set_custom_effect', 'set_key_row']
+
+    DPI_MAX = 18000
+
+    DEVICE_IMAGE = "https://dl.razerzone.com/src/3993-1-EN-V2.png"
+
+    def _suspend_device(self):
+        """
+        Suspend the device
+        Get the current brightness level, store it for later and then set the brightness to 0
+        """
+        self.suspend_args.clear()
+        self.suspend_args['brightness'] = (_da_get_scroll_brightness(self), _get_left_brightness(self))
+
+        # Todo make it context?
+        self.disable_notify = True
+        _da_set_scroll_brightness(self, 0)
+        _set_left_brightness(self, 0)
+        self.disable_notify = False
+
+    def _resume_device(self):
+        """
+        Resume the device
+        Get the last known brightness and then set the brightness
+        """
+        scroll_brightness = self.suspend_args.get('brightness', (100, 100))[0]
+        left_row_brightness = self.suspend_args.get('brightness', (100, 100))[1]
+
+        self.disable_notify = True
+        _da_set_scroll_brightness(self, scroll_brightness)
+        _set_left_brightness(self, left_row_brightness)
+        self.disable_notify = False
+
+
 class RazerDeathAdderV2Mini(__RazerDeviceSpecialBrightnessSuspend):
     """
     Class for the Razer DeathAdder V2 Mini
@@ -2784,6 +2845,8 @@ class RazerDeathAdderV2Mini(__RazerDevic
 
     USB_VID = 0x1532
     USB_PID = 0x008C
+    HAS_MATRIX = True
+    MATRIX_DIMS = [1, 1]
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/1692/deathadder-v2-mini.png"
 
     DPI_MAX = 8500
@@ -2862,7 +2925,7 @@ class RazerViper8KHz(__RazerDevice):
         self.disable_notify = False
 
 
-class RazerNagaEpicChromaWired(__RazerDeviceBrightnessSuspend):
+class RazerNagaEpicChromaWired(__RazerDeviceSpecialBrightnessSuspend):
     """
     Class for the Razer Naga Epic Chroma (Wired)
     """
@@ -2963,7 +3026,7 @@ class RazerDeathAdderV2XHyperSpeed(__Raz
     EVENT_FILE_REGEX = re.compile(r'.*Razer_DeathAdder_V2_X_HyperSpeed_000000000000-if0(1|2)-event-kbd')
     METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages',
                'get_poll_rate', 'set_poll_rate',
-               'get_battery', 'is_charging', 'get_idle_time', 'set_idle_time']
+               'get_battery', 'is_charging', 'get_idle_time', 'set_idle_time', 'set_low_battery_threshold']
 
     USB_VID = 0x1532
     USB_PID = 0x009C
@@ -3004,7 +3067,7 @@ class RazerViperV2ProWired(__RazerDevice
     USB_PID = 0x00A5
     METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages',
                'get_poll_rate', 'set_poll_rate',
-               'get_battery', 'is_charging', 'get_idle_time', 'set_idle_time']
+               'get_battery', 'is_charging', 'get_idle_time', 'set_idle_time', 'set_low_battery_threshold']
 
     DEVICE_IMAGE = "https://dl.razerzone.com/src/6048-1-en-v10.png"
 
@@ -3039,3 +3102,50 @@ class RazerViperV2ProWireless(RazerViper
     """
 
     USB_PID = 0x00A6
+
+
+class RazerDeathAdderV3ProWired(__RazerDevice):
+    """
+    Class for the Razer DeathAdder V3 Pro (Wired)
+    """
+    EVENT_FILE_REGEX = re.compile(r'.*usb-Razer_Razer_DeathAdder_V3_Pro_000000000000-if0(1|2)-event-kbd')
+
+    USB_VID = 0x1532
+    USB_PID = 0x00B6
+    METHODS = ['get_device_type_mouse', 'max_dpi', 'get_dpi_xy', 'set_dpi_xy', 'get_dpi_stages', 'set_dpi_stages',
+               'get_poll_rate', 'set_poll_rate',
+               'get_battery', 'is_charging', 'get_idle_time', 'set_idle_time']
+
+    DEVICE_IMAGE = "https://dl.razerzone.com/src/6130/6130-1-en-v2.png"
+
+    DPI_MAX = 30000
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self._battery_manager = _BatteryManager(self, self._device_number, 'Razer DeathAdder V3 Pro')
+        self._battery_manager.active = self.config.getboolean('Startup', 'battery_notifier', fallback=False)
+        self._battery_manager.frequency = self.config.getint('Startup', 'battery_notifier_freq', fallback=10 * 60)
+        self._battery_manager.percent = self.config.getint('Startup', 'battery_notifier_percent', fallback=33)
+
+    def _close(self):
+        """
+        Close the key manager
+        """
+        super()._close()
+
+        self._battery_manager.close()
+
+    def _resume_device(self):
+        self.logger.debug("Device doesn't have suspend/resume")
+
+    def _suspend_device(self):
+        self.logger.debug("Device doesn't have suspend/resume")
+
+
+class RazerDeathAdderV3ProWireless(RazerDeathAdderV3ProWired):
+    """
+    Class for the Razer DeathAdder V3 Pro (Wireless)
+    """
+
+    USB_PID = 0x00B7
diff -pruN 3.4.0+dfsg-1/daemon/setup.py 3.5.1+dfsg-2/daemon/setup.py
--- 3.4.0+dfsg-1/daemon/setup.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/daemon/setup.py	2022-12-04 11:49:31.000000000 +0000
@@ -5,6 +5,6 @@ from setuptools import setup, find_packa
 
 setup(
     name="openrazer_daemon",
-    version="3.4.0",
+    version="3.5.1",
     packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"])
 )
diff -pruN 3.4.0+dfsg-1/debian/changelog 3.5.1+dfsg-2/debian/changelog
--- 3.4.0+dfsg-1/debian/changelog	2022-08-04 20:45:29.000000000 +0000
+++ 3.5.1+dfsg-2/debian/changelog	2023-02-03 16:07:01.000000000 +0000
@@ -1,3 +1,44 @@
+openrazer (3.5.1+dfsg-2) unstable; urgency=medium
+
+  [ Andreas Beckmann ]
+  * Re-enable Testsuite: autopkgtest-pkg-dkms.
+  * Do not build the module for kernels without CONFIG_USB.
+
+  [ Dylan Aïssi ]
+  * Cherry-pick upstream patch to fix makefile.
+  * Standards-Version: 4.6.2 (no changes required)
+
+ -- Dylan Aïssi <daissi@debian.org>  Fri, 03 Feb 2023 17:07:01 +0100
+
+openrazer (3.5.1+dfsg-1) unstable; urgency=medium
+
+  * New upstream version
+
+ -- Dylan Aïssi <daissi@debian.org>  Sun, 04 Dec 2022 22:20:59 +0100
+
+openrazer (3.5.0+dfsg-1) unstable; urgency=medium
+
+  * New upstream version
+
+ -- Dylan Aïssi <daissi@debian.org>  Sat, 03 Dec 2022 10:50:19 +0100
+
+openrazer (3.4.0+dfsg-2.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * No source change upload to rebuild with debhelper 13.10.
+
+ -- Michael Biebl <biebl@debian.org>  Sat, 15 Oct 2022 11:04:55 +0200
+
+openrazer (3.4.0+dfsg-2) unstable; urgency=medium
+
+  * Patch upstream makefile because of sysconfig default scheme
+      changes (Closes: #1020039)
+  * Disable d/p/0001-usb-hid-disabled-builds.patch for now
+  * Disable Testsuite: autopkgtest-pkg-dkms (Closes: #1018789)
+      Currently broken see #1019425
+
+ -- Dylan Aïssi <daissi@debian.org>  Fri, 07 Oct 2022 17:20:47 +0200
+
 openrazer (3.4.0+dfsg-1) unstable; urgency=medium
 
   * New upstream version
diff -pruN 3.4.0+dfsg-1/debian/control 3.5.1+dfsg-2/debian/control
--- 3.4.0+dfsg-1/debian/control	2022-08-04 20:45:29.000000000 +0000
+++ 3.5.1+dfsg-2/debian/control	2023-02-03 16:07:01.000000000 +0000
@@ -7,7 +7,7 @@ Build-Depends: debhelper-compat (= 13),
                dh-sequence-dkms,
                python3,
                python3-setuptools
-Standards-Version: 4.6.1
+Standards-Version: 4.6.2
 Vcs-Browser: https://salsa.debian.org/debian/openrazer
 Vcs-Git: https://salsa.debian.org/debian/openrazer.git
 Homepage: https://openrazer.github.io/
diff -pruN 3.4.0+dfsg-1/debian/patches/0001-usb-hid-disabled-builds.patch 3.5.1+dfsg-2/debian/patches/0001-usb-hid-disabled-builds.patch
--- 3.4.0+dfsg-1/debian/patches/0001-usb-hid-disabled-builds.patch	2022-08-04 20:45:29.000000000 +0000
+++ 3.5.1+dfsg-2/debian/patches/0001-usb-hid-disabled-builds.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,267 +0,0 @@
-Description: Build in dummy drivers for systems that do not support RAWHID or USB
- Kernels that don't support RAWHID or USB configs will cause this
- driver to fail to build.  Avoid this by disabling the RAWHID and USB
- functionality in the driver and return -ENODEV when the drivers are
- loaded. Also report the reason for failure in the kernel log.
-Author: Colin Ian King <colin.king@ubuntu.com>
-Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/openrazer/+bug/1830055
-Last-Update: 2021-02-24
-
---- a/driver/razeraccessory_driver.c
-+++ b/driver/razeraccessory_driver.c
-@@ -7,13 +7,17 @@
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/init.h>
-+
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
- #include <linux/usb/input.h>
- #include <linux/hid.h>
- #include <linux/random.h>
- 
- #include "razeraccessory_driver.h"
--#include "razercommon.h"
- #include "razerchromacommon.h"
-+#endif
-+
-+#include "razercommon.h"
- 
- /*
-  * Version Information
-@@ -25,6 +29,7 @@
- MODULE_VERSION(DRIVER_VERSION);
- MODULE_LICENSE(DRIVER_LICENSE);
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
- /**
-  * Send report to the device
-  */
-@@ -2116,3 +2121,12 @@
- };
- 
- module_hid_driver(razer_accessory_driver);
-+
-+#else
-+static int razer_init(void)
-+{
-+	pr_err("razeaccessory driver: system not supported, no HID or USB support\n");
-+	return -ENODEV;
-+}
-+module_init(razer_init);
-+#endif
---- a/driver/razerkbd_driver.c
-+++ b/driver/razerkbd_driver.c
-@@ -7,15 +7,20 @@
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/init.h>
-+
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
- #include <linux/usb/input.h>
- #include <linux/hid.h>
- #include <linux/dmi.h>
-+#endif
- 
--#include "usb_hid_keys.h"
-+#include "razercommon.h"
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
-+#include "usb_hid_keys.h"
- #include "razerkbd_driver.h"
--#include "razercommon.h"
- #include "razerchromacommon.h"
-+#endif
- 
- /*
-  * Version Information
-@@ -27,6 +32,8 @@
- MODULE_VERSION(DRIVER_VERSION);
- MODULE_LICENSE(DRIVER_LICENSE);
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
-+
- // M1-M5 is F13-F17
- #define RAZER_MACRO_KEY 188 // 188 = KEY_F18
- #define RAZER_GAME_KEY 189 // 189 = KEY_F19
-@@ -4017,3 +4024,13 @@
- };
- 
- module_hid_driver(razer_kbd_driver);
-+
-+#else
-+static int razer_init(void)
-+{
-+	pr_err("razerkbd: system not supported, no HID or USB support\n");
-+	return -ENODEV;
-+}
-+
-+module_init(razer_init);
-+#endif
---- a/driver/razerkraken_driver.c
-+++ b/driver/razerkraken_driver.c
-@@ -7,11 +7,14 @@
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/init.h>
-+
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
- #include <linux/usb/input.h>
- #include <linux/hid.h>
- #include <linux/random.h>
- 
- #include "razerkraken_driver.h"
-+#endif
- #include "razercommon.h"
- 
- /*
-@@ -24,6 +27,8 @@
- MODULE_VERSION(DRIVER_VERSION);
- MODULE_LICENSE(DRIVER_LICENSE);
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
-+
- /**
-  * Print report to syslog
-  */
-@@ -875,3 +880,13 @@
- };
- 
- module_hid_driver(razer_kraken_driver);
-+
-+#else
-+static int razer_init(void)
-+{
-+	pr_err("razerkraken: system not supported, no HID or USB support\n");
-+	return -ENODEV;
-+}
-+ 
-+module_init(razer_init);
-+#endif
---- a/driver/razermouse_driver.c
-+++ b/driver/razermouse_driver.c
-@@ -7,14 +7,18 @@
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/init.h>
-+
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
- #include <linux/usb/input.h>
- #include <linux/hid.h>
- #include <linux/hrtimer.h>
- #include <linux/random.h>
- 
- #include "razermouse_driver.h"
--#include "razercommon.h"
- #include "razerchromacommon.h"
-+#endif
-+
-+#include "razercommon.h"
- 
- /*
-  * Version Information
-@@ -32,6 +36,7 @@
- MODULE_VERSION(DRIVER_VERSION);
- MODULE_LICENSE(DRIVER_LICENSE);
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
- 
- /**
-  * Send report to the mouse
-@@ -6261,3 +6266,13 @@
- };
- 
- module_hid_driver(razer_mouse_driver);
-+
-+#else
-+static int razer_init(void)
-+{
-+	pr_err("razermouse: system not supported, no HID or USB support\n");
-+	return -ENODEV;
-+}
-+
-+module_init(razer_init);
-+#endif
---- a/driver/razercommon.c
-+++ b/driver/razercommon.c
-@@ -8,6 +8,9 @@
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/init.h>
-+
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
-+
- #include <linux/hid.h>
- 
- 
-@@ -200,6 +203,7 @@
-     return value;
- }
- 
-+#endif
- 
- int razer_send_control_msg_old_device(struct usb_device *usb_dev,void const *data, uint report_value, uint report_index, uint report_size, ulong wait_min, ulong wait_max)
- {
---- a/driver/razercommon.h
-+++ b/driver/razercommon.h
-@@ -7,8 +7,6 @@
- #ifndef DRIVER_RAZERCOMMON_H_
- #define DRIVER_RAZERCOMMON_H_
- 
--#include <linux/usb/input.h>
--
- #define DRIVER_VERSION "3.4.0"
- #define DRIVER_LICENSE "GPL v2"
- #define DRIVER_AUTHOR "Terry Cain <terry@terrys-home.co.uk>"
-@@ -23,6 +21,10 @@
- #endif
- #endif
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
-+
-+#include <linux/usb/input.h>
-+
- // Macro to create device files
- #define CREATE_DEVICE_FILE(dev, type) \
- do { \
-@@ -145,4 +147,5 @@
- unsigned char clamp_u8(unsigned char value, unsigned char min, unsigned char max);
- unsigned short clamp_u16(unsigned short value, unsigned short min, unsigned short max);
- 
-+#endif
- #endif /* DRIVER_RAZERCOMMON_H_ */
---- a/driver/razerchromacommon.h
-+++ b/driver/razerchromacommon.h
-@@ -8,6 +8,8 @@
- 
- #include "razercommon.h"
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
-+
- /*
-  * Standard Device Functions
-  */
-@@ -152,3 +154,5 @@
- struct razer_report razer_chroma_misc_get_scroll_smart_reel(void);
- 
- #endif
-+
-+#endif
---- a/driver/razerchromacommon.c
-+++ b/driver/razerchromacommon.c
-@@ -3,6 +3,8 @@
-  * Copyright (c) 2015 Terry Cain <terrys-home.co.uk>
-  */
- 
-+#if defined(CONFIG_HIDRAW) && (defined(CONFIG_USB) || defined(CONFIG_USB_MODULE))
-+
- #include "razerchromacommon.h"
- 
- 
-@@ -909,6 +911,7 @@
-     return report;
- }
- 
-+#endif
- 
- 
- 
diff -pruN 3.4.0+dfsg-1/debian/patches/6322c4ab9d12b5711eead41821fe19149e515afc.patch 3.5.1+dfsg-2/debian/patches/6322c4ab9d12b5711eead41821fe19149e515afc.patch
--- 3.4.0+dfsg-1/debian/patches/6322c4ab9d12b5711eead41821fe19149e515afc.patch	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/debian/patches/6322c4ab9d12b5711eead41821fe19149e515afc.patch	2023-02-03 16:07:01.000000000 +0000
@@ -0,0 +1,47 @@
+From 6322c4ab9d12b5711eead41821fe19149e515afc Mon Sep 17 00:00:00 2001
+From: Luca Weiss <luca@z3ntu.xyz>
+Date: Fri, 16 Dec 2022 18:45:34 +0100
+Subject: [PATCH] debian: replace python packaging hacks
+
+It seems Debian setuputils can just use --install-layout=deb to move the
+files to the correct location. This allows us to remove the manual
+moving around of directories that was present until now.
+---
+ Makefile        | 2 --
+ daemon/Makefile | 2 +-
+ pylib/Makefile  | 2 +-
+ 3 files changed, 2 insertions(+), 4 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -167,8 +167,6 @@
+ ubuntu_install: setup_dkms ubuntu_udev_install ubuntu_daemon_install ubuntu_python_library_install appstream_install
+ 	@echo -e "\n::\033[34m Installing for Ubuntu\033[0m"
+ 	@echo "====================================================="
+-	mv $(DESTDIR)$(PREFIX)/lib/python3.* $(DESTDIR)$(PREFIX)/lib/python3
+-	mv $(DESTDIR)$(PREFIX)/lib/python3/site-packages $(DESTDIR)$(PREFIX)/lib/python3/dist-packages
+ 
+ install_i_know_what_i_am_doing: all driver_install udev_install python_library_install
+ 	@make --no-print-directory -C daemon install DESTDIR=$(DESTDIR)
+--- a/daemon/Makefile
++++ b/daemon/Makefile
+@@ -22,7 +22,7 @@
+ 	python3 setup.py install --prefix=$(PREFIX) --root=$(DESTDIR)
+ 
+ ubuntu_install: purge_pycache manpages install-resources
+-	python3 setup.py install --prefix=$(PREFIX) --root=$(DESTDIR) --no-compile
++	python3 setup.py install --prefix=$(PREFIX) --root=$(DESTDIR) --no-compile --install-layout=deb
+ 
+ manpages:
+ 	@install -m 644 -D -v resources/man/razer.conf.5 $(DESTDIR)$(PREFIX)/share/man/man5/razer.conf.5
+--- a/pylib/Makefile
++++ b/pylib/Makefile
+@@ -9,7 +9,7 @@
+ 	python3 setup.py install --prefix=/usr --root=$(DESTDIR)
+ 
+ ubuntu_install: purge_pycache
+-	python3 setup.py install --prefix=/usr --root=$(DESTDIR) --no-compile
++	python3 setup.py install --prefix=/usr --root=$(DESTDIR) --no-compile --install-layout=deb
+ 
+ uninstall:
+ 	$(eval DAEMONPATH := $(shell find $(DESTDIR)/usr/lib/python3* -maxdepth 2 -name "razer"))
diff -pruN 3.4.0+dfsg-1/debian/patches/series 3.5.1+dfsg-2/debian/patches/series
--- 3.4.0+dfsg-1/debian/patches/series	2022-08-04 20:45:29.000000000 +0000
+++ 3.5.1+dfsg-2/debian/patches/series	2023-02-03 16:07:01.000000000 +0000
@@ -1 +1,2 @@
-0001-usb-hid-disabled-builds.patch
+6322c4ab9d12b5711eead41821fe19149e515afc.patch
+skip-without-CONFIG_USB.patch
diff -pruN 3.4.0+dfsg-1/debian/patches/skip-without-CONFIG_USB.patch 3.5.1+dfsg-2/debian/patches/skip-without-CONFIG_USB.patch
--- 3.4.0+dfsg-1/debian/patches/skip-without-CONFIG_USB.patch	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/debian/patches/skip-without-CONFIG_USB.patch	2023-02-03 16:07:01.000000000 +0000
@@ -0,0 +1,10 @@
+--- a/install_files/dkms/dkms.conf
++++ b/install_files/dkms/dkms.conf
+@@ -1,6 +1,7 @@
+ PACKAGE_NAME="openrazer-driver"
+ PACKAGE_VERSION="3.5.1"
+ AUTOINSTALL="yes"
++BUILD_EXCLUSIVE_CONFIG="CONFIG_USB"
+ MAKE="KERNELDIR=/lib/modules/${kernelver}/build make driver"
+ 
+ BUILT_MODULE_NAME[0]="razerkbd"
diff -pruN 3.4.0+dfsg-1/DEVELOPMENT.md 3.5.1+dfsg-2/DEVELOPMENT.md
--- 3.4.0+dfsg-1/DEVELOPMENT.md	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/DEVELOPMENT.md	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,153 @@
+# Development
+
+## Introduction
+
+OpenRazer consists of a Linux kernel module and Python daemon + library. The Linux kernel module exposes an
+sysfs interface, the Python daemon (openrazer-daemon) exposes this on it's turn over D-Bus.
+
+It also includes a Python libraries for applications and scripts to use that talks to the daemon over D-Bus.
+
+If you want to add support for a new hardware device it's often required to make changes to both the kernel module
+(`driver/`) and the Python sources (`daemon/`).
+
+Some other files that need modifying are:
+* `README.md`
+* `install_files/udev/99-razer.rules`
+* `install_files/appstream/io.github.openrazer.openrazer.metainfo.xml`: generate with `./scripts/generate_appstream_file.sh`
+* `pylib/openrazer/_fake_driver/*.cfg`: generate with `./scripts/generate_all_fake_drivers.sh -f`
+
+Generally it's helpful to look at recent commits adding new devices and doing similar changes for your device.
+
+This description assumes you have cloned the openrazer repository to your home directory.
+
+## Setup your development environment
+
+These instructions should help you setup a development environment for both the kernel module and Python
+daemon.
+
+### Kernel module
+
+It is possible to do development and test your changes on your local system but you risk kernel panics and therefore
+possibly some data loss. Therefore it's recommended to do your development on a separate virtual or physical machine.
+
+When you forward a USB device to the virtual machine, it becomes inaccessible for the host, so if you forward your
+keyboard make sure you have a second one attached so you can still control your host.
+
+I had some success with QEMU on Linux with the following.
+
+To add a device to QEMU (change hostbus/hostaddr to the Razer device):
+```
+device_add usb-host,id=razer,hostbus=5,hostaddr=2
+```
+
+and to remove the device from the virtual machine:
+```
+device_del razer
+```
+
+If you're on macOS or Windows I recommend to use VirtualBox and use USB passthough as described here:
+[VirtualBox USB Support](https://www.virtualbox.org/manual/ch03.html#settings-usb)
+
+Make sure you're using the same kernel version on both your development as your test machine. Easiest way
+to achieve this is to use the same Linux distribution and use the latest available kernel version.
+
+#### Debian/Ubuntu
+
+For Debian/Ubuntu install the following packages for kernel development:
+
+```
+apt-get install -y make gcc flex bison bc linux-headers-$(uname -r)
+```
+
+#### RedHat/Fedora
+
+For RedHat/Fedora install the following packages for kernel development:
+
+```
+dnf install -y binutils make gcc ncurses-devel sed flex bison kernel-headers
+```
+
+#### Build the kernel module
+
+Run the following command to build the kernel module:
+
+```
+make driver
+```
+
+This will build the kernel modules in `driver/*.ko`. If you make changes to the sources
+you can rerun the `make driver` command and the modules will be rebuild.
+
+
+#### Test the kernel module
+
+You can copy the `driver/*.ko` modules to your test system and (re)load for example
+the keyboard module using:
+
+```
+rmmod razerkbd && insmod razerkbd.ko
+```
+
+If you update the kernel module you have to manually reload the module.
+
+Driver messages can be found by running:
+
+```
+dmesg
+```
+
+### Python daemon
+
+OpenRazer can only use your system site-packages and cannot be (easily) installed in
+a virtualenv. Therefore you will have to install the dependencies on your system and
+set your PYTHONPATH so you can run from sources.
+
+#### Debian/Ubuntu
+
+For Debian/Ubuntu install the following packages to be able to run the daemon:
+
+```
+apt-get install -y python3 python3-daemonize python3-dbus python3-gi python3-notify2 python3-numpy python3-pyudev python3-setproctitle
+```
+
+#### RedHat/Fedora
+
+For RedHat/Fedora install the following packages to be able to run the daemon:
+
+```
+dnf install -y python3 python3-daemonize python3-dbus python3-notify2 python3-numpy python3-pyudev python3-setproctitle
+```
+
+#### Test the daemon
+
+Copy or have another clone of openrazer on your test system.
+
+Run:
+
+```
+PYTHONPATH="pylib:daemon" python3 ./daemon/run_openrazer_daemon.py -Fv --config=$PWD/daemon/resources/razer.conf
+```
+
+## Contribute back your changes!
+
+### Prerequisites
+
+The OpenRazer code is licensed under the GPL-2.0-or-later license. Make sure you understand what this means. Please
+also be sure that if your changes include work done by others they also agree with publishing under this license.
+
+If you haven't already you'll have to sign up for a GitHub account, fork this repository and push your changes to a
+branch in this fork.
+
+### Check if there's a issue for what you've fixed
+
+Please search our issues to see if you've fixed something that has been reported by someone already. If you're
+adding support for a new device please create a new github issue.
+
+### Create a new pull request
+
+[Create a new pull request](https://github.com/openrazer/openrazer/compare) and please properly describe your changes.
+
+Keep in mind, OpenRazer is an open source project managed by volunteers, we really appreciate your work but
+everything is done as a best effort.
+
+Even if your changes work we could decide they're not suitable for OpenRazer or require changes.
diff -pruN 3.4.0+dfsg-1/driver/razeraccessory_driver.c 3.5.1+dfsg-2/driver/razeraccessory_driver.c
--- 3.4.0+dfsg-1/driver/razeraccessory_driver.c	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razeraccessory_driver.c	2022-12-04 11:49:31.000000000 +0000
@@ -181,6 +181,10 @@ static ssize_t razer_attr_read_device_ty
         device_type = "Razer Raptor 27\n";
         break;
 
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
+        device_type = "Razer Chroma Addressable RGB Controller\n";
+        break;
+
     default:
         device_type = "Unknown Device\n";
         break;
@@ -236,6 +240,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_NOMMO_PRO:
     case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
     case USB_DEVICE_ID_RAZER_MOUSE_DOCK:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         report = razer_chroma_extended_matrix_effect_spectrum(VARSTORE, ZERO_LED);
         report.transaction_id.id = 0x3F;
         break;
@@ -375,6 +380,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_NOMMO_PRO:
     case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
     case USB_DEVICE_ID_RAZER_MOUSE_DOCK:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         report = razer_chroma_extended_matrix_effect_none(VARSTORE, ZERO_LED);
         report.transaction_id.id = 0x3F;
         break;
@@ -462,6 +468,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_NOMMO_PRO:
     case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
     case USB_DEVICE_ID_RAZER_MOUSE_DOCK:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         report = razer_chroma_extended_matrix_effect_custom_frame();
         break;
 
@@ -519,6 +526,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_NOMMO_PRO:
     case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
     case USB_DEVICE_ID_RAZER_MOUSE_DOCK:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         report = razer_chroma_extended_matrix_effect_static(VARSTORE, ZERO_LED, (struct razer_rgb*) & buf[0]);
         report.transaction_id.id = 0x3F;
         break;
@@ -605,6 +613,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_NOMMO_PRO:
     case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
     case USB_DEVICE_ID_RAZER_MOUSE_DOCK:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         report = razer_chroma_extended_matrix_effect_wave(VARSTORE, ZERO_LED, direction);
         report.transaction_id.id = 0x3F;
         break;
@@ -660,6 +669,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_NOMMO_PRO:
     case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
     case USB_DEVICE_ID_RAZER_MOUSE_DOCK:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         switch(count) {
         case 3: // Single colour mode
             report = razer_chroma_extended_matrix_effect_breathing_single(VARSTORE, ZERO_LED, (struct razer_rgb *)&buf[0]);
@@ -885,6 +895,10 @@ static ssize_t razer_attr_write_matrix_c
             report.transaction_id.id = 0x1F;
             break;
 
+        case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
+            razer_send_argb_msg(device->usb_dev, row_id, (stop_col - start_col) + 1, (unsigned char*)&buf[offset]);
+            return count;
+
         default:
             printk(KERN_WARNING "razeraccessory: Unknown device\n");
             return -EINVAL;
@@ -929,6 +943,7 @@ static ssize_t razer_attr_read_device_se
     case USB_DEVICE_ID_RAZER_NOMMO_PRO:
     case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
     case USB_DEVICE_ID_RAZER_MOUSE_DOCK:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         response_report = razer_send_payload(device->usb_dev, &report);
         strncpy(&serial_string[0], &response_report.arguments[0], 22);
         serial_string[22] = '\0';
@@ -1124,6 +1139,36 @@ static ssize_t razer_attr_write_matrix_b
         report = razer_chroma_extended_matrix_brightness(VARSTORE, ZERO_LED, brightness);
         break;
 
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
+        /* Set the brightness for all channels to the requested value */
+        report = razer_chroma_extended_matrix_brightness(VARSTORE, ARGB_CH_1_LED, brightness);
+        mutex_lock(&device->lock);
+        razer_send_payload(device->usb_dev, &report);
+        mutex_unlock(&device->lock);
+
+        report = razer_chroma_extended_matrix_brightness(VARSTORE, ARGB_CH_2_LED, brightness);
+        mutex_lock(&device->lock);
+        razer_send_payload(device->usb_dev, &report);
+        mutex_unlock(&device->lock);
+
+        report = razer_chroma_extended_matrix_brightness(VARSTORE, ARGB_CH_3_LED, brightness);
+        mutex_lock(&device->lock);
+        razer_send_payload(device->usb_dev, &report);
+        mutex_unlock(&device->lock);
+
+        report = razer_chroma_extended_matrix_brightness(VARSTORE, ARGB_CH_4_LED, brightness);
+        mutex_lock(&device->lock);
+        razer_send_payload(device->usb_dev, &report);
+        mutex_unlock(&device->lock);
+
+        report = razer_chroma_extended_matrix_brightness(VARSTORE, ARGB_CH_5_LED, brightness);
+        mutex_lock(&device->lock);
+        razer_send_payload(device->usb_dev, &report);
+        mutex_unlock(&device->lock);
+
+        report = razer_chroma_extended_matrix_brightness(VARSTORE, ARGB_CH_6_LED, brightness);
+        break;
+
     default:
         printk(KERN_WARNING "razeraccessory: Unknown device\n");
         return -EINVAL;
@@ -1144,9 +1189,11 @@ static ssize_t razer_attr_write_matrix_b
 static ssize_t razer_attr_read_matrix_brightness(struct device *dev, struct device_attribute *attr, char *buf)
 {
     struct razer_accessory_device *device = dev_get_drvdata(dev);
-    struct razer_report report = razer_chroma_standard_get_led_brightness(VARSTORE, BACKLIGHT_LED);
     struct razer_report response = {0};
     unsigned char brightness = 0;
+    struct razer_report report;
+    size_t sum = 0;
+    size_t i;
 
     switch (device->usb_dev->descriptor.idProduct) {
     case USB_DEVICE_ID_RAZER_FIREFLY_HYPERFLUX:
@@ -1163,7 +1210,20 @@ static ssize_t razer_attr_read_matrix_br
         brightness = device->saved_brightness;
         break;
 
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
+        /* Get the average brightness of all channels */
+        for (i = ARGB_CH_1_LED; i <= ARGB_CH_6_LED; i++) {
+            report = razer_chroma_extended_matrix_get_brightness(VARSTORE, i);
+            mutex_lock(&device->lock);
+            response = razer_send_payload(device->usb_dev, &report);
+            mutex_unlock(&device->lock);
+            sum += response.arguments[2];
+        }
+        brightness = sum / 6;
+        break;
+
     default:
+        report = razer_chroma_standard_get_led_brightness(VARSTORE, BACKLIGHT_LED);
         mutex_lock(&device->lock);
         response = razer_send_payload(device->usb_dev, &report);
         mutex_unlock(&device->lock);
@@ -1549,9 +1609,277 @@ static ssize_t razer_attr_write_fully_ch
     return razer_attr_write_matrix_effect_breath_common(dev, attr, buf, count, FULLY_CHARGED_LED);
 }
 
+/**
+ * Sets the brightness to the ASCII number
+ */
+static ssize_t razer_attr_write_channel_led_brightness(unsigned char led, struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    struct razer_accessory_device *device = dev_get_drvdata(dev);
+    unsigned char brightness = 0;
+    struct razer_report report = {0};
+
+    if (count < 1) {
+        printk(KERN_WARNING "razeraccessory: Brightness takes an ascii number\n");
+        return -EINVAL;
+    }
+
+    brightness = (unsigned char)simple_strtoul(buf, NULL, 10);
+
+    report = razer_chroma_extended_matrix_brightness(VARSTORE, led, brightness);
+
+    mutex_lock(&device->lock);
+    razer_send_payload(device->usb_dev, &report);
+    mutex_unlock(&device->lock);
+
+    return count;
+}
+
+static ssize_t razer_attr_write_channel1_led_brightness(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_led_brightness(ARGB_CH_1_LED, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel2_led_brightness(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_led_brightness(ARGB_CH_2_LED, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel3_led_brightness(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_led_brightness(ARGB_CH_3_LED, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel4_led_brightness(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_led_brightness(ARGB_CH_4_LED, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel5_led_brightness(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_led_brightness(ARGB_CH_5_LED, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel6_led_brightness(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_led_brightness(ARGB_CH_6_LED, dev, attr, buf, count);
+}
+
+/**
+ * Read device file "channelX_size"
+ */
+static ssize_t razer_attr_read_channel_size(unsigned int channel, struct device *dev, struct device_attribute *attr, char *buf)
+{
+    struct razer_accessory_device *device = dev_get_drvdata(dev);
+    struct razer_report report = get_razer_report(0x0f, 0x88, 0x0d);
+    struct razer_report response;
+    report.transaction_id.id = 0x1F;
+    report.arguments[0] = 0x06;
+
+    mutex_lock(&device->lock);
+    response = razer_send_payload(device->usb_dev, &report);
+    mutex_unlock(&device->lock);
+
+    return sprintf(buf, "%d\n", response.arguments[channel * 2]);
+}
+
+static ssize_t razer_attr_read_channel1_size(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_size(1, dev, attr, buf);
+}
+
+static ssize_t razer_attr_read_channel2_size(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_size(2, dev, attr, buf);
+}
+
+static ssize_t razer_attr_read_channel3_size(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_size(3, dev, attr, buf);
+}
+
+static ssize_t razer_attr_read_channel4_size(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_size(4, dev, attr, buf);
+}
+
+static ssize_t razer_attr_read_channel5_size(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_size(5, dev, attr, buf);
+}
+
+static ssize_t razer_attr_read_channel6_size(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_size(6, dev, attr, buf);
+}
+
+/**
+ * Write device file "channelX_size"
+ */
+static ssize_t razer_attr_write_channel_size(unsigned int channel, struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    struct razer_report response;
+    unsigned char sz;
+    struct razer_report report;
+    struct razer_accessory_device *device;
+
+    if (count < 1) {
+        printk(KERN_WARNING "razeraccessory: Size takes an ascii number\n");
+        return -EINVAL;
+    }
+
+    device = dev_get_drvdata(dev);
+
+    /* Get existing sizes */
+    report = get_razer_report(0x0f, 0x88, 0x0d);
+    report.transaction_id.id = 0x1F;
+    report.arguments[0] = 0x06;
+
+    mutex_lock(&device->lock);
+    response = razer_send_payload(device->usb_dev, &report);
+    mutex_unlock(&device->lock);
+
+    /* Set new sizes */
+    sz = (unsigned char)simple_strtoul(buf, NULL, 10);
+
+    report = get_razer_report(0x0f, 0x08, 0x0d);
+    report.arguments[0] = 0x06;
+    report.arguments[1] = 0x01;
+    report.arguments[2] = channel == 1 ? sz : response.arguments[2];
+    report.arguments[3] = 0x02;
+    report.arguments[4] = channel == 2 ? sz : response.arguments[4];
+    report.arguments[5] = 0x03;
+    report.arguments[6] = channel == 3 ? sz : response.arguments[6];
+    report.arguments[7] = 0x04;
+    report.arguments[8] = channel == 4 ? sz : response.arguments[8];
+    report.arguments[9] = 0x05;
+    report.arguments[10] = channel == 5 ? sz : response.arguments[10];
+    report.arguments[11] = 0x06;
+    report.arguments[12] = channel == 6 ? sz : response.arguments[12];
+
+    mutex_lock(&device->lock);
+    razer_send_payload(device->usb_dev, &report);
+    mutex_unlock(&device->lock);
+
+    return count;
+}
+
+static ssize_t razer_attr_write_channel1_size(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_size(1, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel2_size(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_size(2, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel3_size(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_size(3, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel4_size(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_size(4, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel5_size(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_size(5, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_channel6_size(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    return razer_attr_write_channel_size(6, dev, attr, buf, count);
+}
+
+static ssize_t razer_attr_write_reset_channels(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    struct razer_accessory_device *device = dev_get_drvdata(dev);
+
+    /* Get existing sizes */
+    struct razer_report report;
+    struct razer_report response = {0};
+    unsigned int i;
+
+    for (i = 0; i < 6; i++) {
+        report = get_razer_report(0x0f, 0x04, 0x03);
+        report.transaction_id.id = 0x1F;
+        report.arguments[0] = 0x01;
+        report.arguments[1] = ARGB_CH_1_LED + i;
+        report.arguments[2] = 0xff;
+
+        mutex_lock(&device->lock);
+        response = razer_send_payload(device->usb_dev, &report);
+        mutex_unlock(&device->lock);
+    }
+
+    report = get_razer_report(0x00, 0xb7, 0x01);
+    report.transaction_id.id = 0x1F;
+    report.arguments[0] = 0x00;
+    mutex_lock(&device->lock);
+    response = razer_send_payload(device->usb_dev, &report);
+    mutex_unlock(&device->lock);
+
+    report = get_razer_report(0x00, 0x36, 0x01);
+    report.transaction_id.id = 0x1F;
+    report.arguments[0] = 0x01;
+    mutex_lock(&device->lock);
+    response = razer_send_payload(device->usb_dev, &report);
+    mutex_unlock(&device->lock);
+
+    return count;
+}
+
+/**
+ * Read device file "channelX_led_brightness"
+ *
+ * Returns brightness or -1 if the initial brightness is not known
+ */
+static ssize_t razer_attr_read_channel_led_brightness(unsigned char led, struct device *dev, struct device_attribute *attr, char *buf)
+{
+    struct razer_accessory_device *device = dev_get_drvdata(dev);
+    struct razer_report report = razer_chroma_extended_matrix_get_brightness(VARSTORE, led);
+    struct razer_report response = {0};
+    unsigned char brightness = 0;
+
+    mutex_lock(&device->lock);
+    response = razer_send_payload(device->usb_dev, &report);
+    mutex_unlock(&device->lock);
+    brightness = response.arguments[2];
+
+    return sprintf(buf, "%d\n", brightness);
+}
+
+static ssize_t razer_attr_read_channel1_led_brightness(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_led_brightness(ARGB_CH_1_LED, dev, attr, buf);
+}
 
+static ssize_t razer_attr_read_channel2_led_brightness(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_led_brightness(ARGB_CH_2_LED, dev, attr, buf);
+}
 
+static ssize_t razer_attr_read_channel3_led_brightness(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_led_brightness(ARGB_CH_3_LED, dev, attr, buf);
+}
+
+static ssize_t razer_attr_read_channel4_led_brightness(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_led_brightness(ARGB_CH_4_LED, dev, attr, buf);
+}
 
+static ssize_t razer_attr_read_channel5_led_brightness(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_led_brightness(ARGB_CH_5_LED, dev, attr, buf);
+}
+
+static ssize_t razer_attr_read_channel6_led_brightness(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    return razer_attr_read_channel_led_brightness(ARGB_CH_6_LED, dev, attr, buf);
+}
 
 /**
  * Set up the device driver files
@@ -1603,6 +1931,20 @@ static DEVICE_ATTR(fully_charged_matrix_
 static DEVICE_ATTR(fully_charged_matrix_effect_static,      0220, NULL,                                           razer_attr_write_fully_charged_matrix_effect_static);
 static DEVICE_ATTR(fully_charged_matrix_effect_none,        0220, NULL,                                           razer_attr_write_fully_charged_matrix_effect_none);
 
+static DEVICE_ATTR(reset_channels,                          0220, NULL,                                           razer_attr_write_reset_channels);
+static DEVICE_ATTR(channel1_size,                           0660, razer_attr_read_channel1_size,                  razer_attr_write_channel1_size);
+static DEVICE_ATTR(channel2_size,                           0660, razer_attr_read_channel2_size,                  razer_attr_write_channel2_size);
+static DEVICE_ATTR(channel3_size,                           0660, razer_attr_read_channel3_size,                  razer_attr_write_channel3_size);
+static DEVICE_ATTR(channel4_size,                           0660, razer_attr_read_channel4_size,                  razer_attr_write_channel4_size);
+static DEVICE_ATTR(channel5_size,                           0660, razer_attr_read_channel5_size,                  razer_attr_write_channel5_size);
+static DEVICE_ATTR(channel6_size,                           0660, razer_attr_read_channel6_size,                  razer_attr_write_channel6_size);
+static DEVICE_ATTR(channel1_led_brightness,                 0660, razer_attr_read_channel1_led_brightness,        razer_attr_write_channel1_led_brightness);
+static DEVICE_ATTR(channel2_led_brightness,                 0660, razer_attr_read_channel2_led_brightness,        razer_attr_write_channel2_led_brightness);
+static DEVICE_ATTR(channel3_led_brightness,                 0660, razer_attr_read_channel3_led_brightness,        razer_attr_write_channel3_led_brightness);
+static DEVICE_ATTR(channel4_led_brightness,                 0660, razer_attr_read_channel4_led_brightness,        razer_attr_write_channel4_led_brightness);
+static DEVICE_ATTR(channel5_led_brightness,                 0660, razer_attr_read_channel5_led_brightness,        razer_attr_write_channel5_led_brightness);
+static DEVICE_ATTR(channel6_led_brightness,                 0660, razer_attr_read_channel6_led_brightness,        razer_attr_write_channel6_led_brightness);
+
 static DEVICE_ATTR(is_mug_present,                          0440, razer_attr_read_is_mug_present,                 NULL);
 
 void razer_accessory_init(struct razer_accessory_device *dev, struct usb_interface *intf, struct hid_device *hdev)
@@ -1680,6 +2022,7 @@ static bool razer_accessory_match(struct
     case USB_DEVICE_ID_RAZER_MOUSE_BUNGEE_V3_CHROMA:
     case USB_DEVICE_ID_RAZER_BASE_STATION_V2_CHROMA:
     case USB_DEVICE_ID_RAZER_CHARGING_PAD_CHROMA:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         if (intf->cur_altsetting->desc.bInterfaceNumber != 0) {
             dev_info(&intf->dev, "skipping secondary interface\n");
             return false;
@@ -1719,6 +2062,7 @@ static int razer_accessory_probe(struct
     case USB_DEVICE_ID_RAZER_THUNDERBOLT_4_DOCK_CHROMA:
     case USB_DEVICE_ID_RAZER_CHARGING_PAD_CHROMA:
     case USB_DEVICE_ID_RAZER_RAPTOR_27:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         expected_protocol = 0;
         break;
 
@@ -1802,6 +2146,7 @@ static int razer_accessory_probe(struct
         case USB_DEVICE_ID_RAZER_CHROMA_MUG:
         case USB_DEVICE_ID_RAZER_CHROMA_BASE:
         case USB_DEVICE_ID_RAZER_CHROMA_HDK:
+        case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         case USB_DEVICE_ID_RAZER_KRAKEN_KITTY_EDITION:
         case USB_DEVICE_ID_RAZER_MOUSE_BUNGEE_V3_CHROMA:
         case USB_DEVICE_ID_RAZER_BASE_STATION_V2_CHROMA:
@@ -1819,6 +2164,7 @@ static int razer_accessory_probe(struct
         case USB_DEVICE_ID_RAZER_CORE:
         case USB_DEVICE_ID_RAZER_CHROMA_MUG:
         case USB_DEVICE_ID_RAZER_CHROMA_HDK:
+        case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         case USB_DEVICE_ID_RAZER_CHROMA_BASE:
         case USB_DEVICE_ID_RAZER_NOMMO_PRO:
         case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
@@ -1859,6 +2205,24 @@ static int razer_accessory_probe(struct
         }
 
         switch(usb_dev->descriptor.idProduct) {
+        case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_reset_channels);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel1_size);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel2_size);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel3_size);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel4_size);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel5_size);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel6_size);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel1_led_brightness);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel2_led_brightness);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel3_led_brightness);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel4_led_brightness);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel5_led_brightness);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_channel6_led_brightness);
+            break;
+        }
+
+        switch(usb_dev->descriptor.idProduct) {
         case USB_DEVICE_ID_RAZER_KRAKEN_KITTY_EDITION:
         // Needs to be in "Normal" mode for idle effects to function properly
         case USB_DEVICE_ID_RAZER_CHARGING_PAD_CHROMA:
@@ -1917,6 +2281,7 @@ static void razer_accessory_disconnect(s
     case USB_DEVICE_ID_RAZER_THUNDERBOLT_4_DOCK_CHROMA:
     case USB_DEVICE_ID_RAZER_CHARGING_PAD_CHROMA:
     case USB_DEVICE_ID_RAZER_RAPTOR_27:
+    case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         expected_protocol = 0;
         break;
 
@@ -1987,6 +2352,7 @@ static void razer_accessory_disconnect(s
         case USB_DEVICE_ID_RAZER_CHROMA_MUG:
         case USB_DEVICE_ID_RAZER_CHROMA_BASE:
         case USB_DEVICE_ID_RAZER_CHROMA_HDK:
+        case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         case USB_DEVICE_ID_RAZER_KRAKEN_KITTY_EDITION:
         case USB_DEVICE_ID_RAZER_MOUSE_BUNGEE_V3_CHROMA:
         case USB_DEVICE_ID_RAZER_BASE_STATION_V2_CHROMA:
@@ -2007,6 +2373,7 @@ static void razer_accessory_disconnect(s
         case USB_DEVICE_ID_RAZER_CHROMA_BASE:
         case USB_DEVICE_ID_RAZER_NOMMO_PRO:
         case USB_DEVICE_ID_RAZER_NOMMO_CHROMA:
+        case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
         case USB_DEVICE_ID_RAZER_KRAKEN_KITTY_EDITION:
         case USB_DEVICE_ID_RAZER_MOUSE_BUNGEE_V3_CHROMA:
         case USB_DEVICE_ID_RAZER_BASE_STATION_V2_CHROMA:
@@ -2041,6 +2408,24 @@ static void razer_accessory_disconnect(s
             device_remove_file(&hdev->dev, &dev_attr_matrix_effect_starlight);
             break;
         }
+
+        switch(usb_dev->descriptor.idProduct) {
+        case USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER:
+            device_remove_file(&hdev->dev, &dev_attr_reset_channels);
+            device_remove_file(&hdev->dev, &dev_attr_channel1_size);
+            device_remove_file(&hdev->dev, &dev_attr_channel2_size);
+            device_remove_file(&hdev->dev, &dev_attr_channel3_size);
+            device_remove_file(&hdev->dev, &dev_attr_channel4_size);
+            device_remove_file(&hdev->dev, &dev_attr_channel5_size);
+            device_remove_file(&hdev->dev, &dev_attr_channel6_size);
+            device_remove_file(&hdev->dev, &dev_attr_channel1_led_brightness);
+            device_remove_file(&hdev->dev, &dev_attr_channel2_led_brightness);
+            device_remove_file(&hdev->dev, &dev_attr_channel3_led_brightness);
+            device_remove_file(&hdev->dev, &dev_attr_channel4_led_brightness);
+            device_remove_file(&hdev->dev, &dev_attr_channel5_led_brightness);
+            device_remove_file(&hdev->dev, &dev_attr_channel6_led_brightness);
+            break;
+        }
     }
 
     hid_hw_stop(hdev);
@@ -2090,6 +2475,7 @@ static const struct hid_device_id razer_
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_NOMMO_PRO) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_NOMMO_CHROMA) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_KRAKEN_KITTY_EDITION) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_MOUSE_BUNGEE_V3_CHROMA) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_THUNDERBOLT_4_DOCK_CHROMA) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BASE_STATION_V2_CHROMA) },
diff -pruN 3.4.0+dfsg-1/driver/razeraccessory_driver.h 3.5.1+dfsg-2/driver/razeraccessory_driver.h
--- 3.4.0+dfsg-1/driver/razeraccessory_driver.h	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razeraccessory_driver.h	2022-12-04 11:49:31.000000000 +0000
@@ -21,6 +21,7 @@
 #define USB_DEVICE_ID_RAZER_RAPTOR_27 0x0F12
 #define USB_DEVICE_ID_RAZER_KRAKEN_KITTY_EDITION 0x0F19
 #define USB_DEVICE_ID_RAZER_MOUSE_BUNGEE_V3_CHROMA 0x0F1D
+#define USB_DEVICE_ID_RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER 0x0F1F
 #define USB_DEVICE_ID_RAZER_BASE_STATION_V2_CHROMA 0x0F20
 #define USB_DEVICE_ID_RAZER_THUNDERBOLT_4_DOCK_CHROMA 0x0F21
 #define USB_DEVICE_ID_RAZER_CHARGING_PAD_CHROMA 0x0F26
diff -pruN 3.4.0+dfsg-1/driver/razerchromacommon.c 3.5.1+dfsg-2/driver/razerchromacommon.c
--- 3.4.0+dfsg-1/driver/razerchromacommon.c	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razerchromacommon.c	2022-12-04 11:49:31.000000000 +0000
@@ -1229,8 +1229,8 @@ struct razer_report razer_chroma_misc_se
     struct razer_report report = get_razer_report(0x04, 0x05, 0x07);
 
     // Keep the DPI within bounds
-    dpi_x = clamp_u16(dpi_x, 100, 26000);
-    dpi_y = clamp_u16(dpi_y, 100, 26000);
+    dpi_x = clamp_u16(dpi_x, 100, 30000);
+    dpi_y = clamp_u16(dpi_y, 100, 30000);
 
     report.arguments[0] = VARSTORE;
 
diff -pruN 3.4.0+dfsg-1/driver/razercommon.c 3.5.1+dfsg-2/driver/razercommon.c
--- 3.4.0+dfsg-1/driver/razercommon.c	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razercommon.c	2022-12-04 11:49:31.000000000 +0000
@@ -107,6 +107,14 @@ int razer_get_usb_response(struct usb_de
         result = 1;
     }
 
+    if (WARN_ONCE(response_report->data_size > ARRAY_SIZE(response_report->arguments),
+                  "Field data_size %d in response is bigger than arguments\n",
+                  response_report->data_size)) {
+        /* Sanitize the value since at the moment callers don't respect the return code */
+        response_report->data_size = ARRAY_SIZE(response_report->arguments);
+        return -EINVAL;
+    }
+
     return result;
 }
 
@@ -167,11 +175,13 @@ struct razer_report get_empty_razer_repo
  */
 void print_erroneous_report(struct razer_report* report, char* driver_name, char* message)
 {
-    printk(KERN_WARNING "%s: %s. Start Marker: %02x id: %02x Num Params: %02x Reserved: %02x Command: %02x Params: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x .\n",
+    printk(KERN_WARNING "%s: %s. status: %02x transaction_id.id: %02x remaining_packets: %02x protocol_type: %02x data_size: %02x, command_class: %02x, command_id.id: %02x Params: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x .\n",
            driver_name,
            message,
            report->status,
            report->transaction_id.id,
+           report->remaining_packets,
+           report->protocol_type,
            report->data_size,
            report->command_class,
            report->command_id.id,
@@ -231,3 +241,51 @@ int razer_send_control_msg_old_device(st
 
     return ((len < 0) ? len : ((len != report_size) ? -EIO : 0));
 }
+
+int razer_send_argb_msg(struct usb_device* usb_dev, unsigned char channel, unsigned char size, void const* data)
+{
+    uint request = HID_REQ_SET_REPORT; // 0x09
+    uint request_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT; // 0x21
+    uint value = 0x300;
+    int len;
+    char *buf;
+
+    struct razer_argb_report report;
+
+    if (channel < 5) {
+        report.report_id = 0x04;
+    } else {
+        report.report_id = 0x84;
+    }
+
+    report.channel_1 = channel;
+    report.channel_2 = channel;
+
+    report.pad = 0;
+
+    report.last_idx = size - 1;
+
+    if (size * 3 > ARRAY_SIZE(report.color_data)) {
+        printk(KERN_ERR "razer driver: size too big\n");
+        return -EINVAL;
+    }
+
+    memcpy(report.color_data, data, size * 3);
+
+    buf = kmemdup(&report, sizeof(report), GFP_KERNEL);
+
+    // Send usb control message
+    len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+                          request,            // Request
+                          request_type,       // RequestType
+                          value,              // Value
+                          0x01,               // Index
+                          buf,                // Data
+                          sizeof(report),     // Length
+                          USB_CTRL_SET_TIMEOUT);
+
+    if (len != sizeof(report))
+        printk(KERN_WARNING "razer driver: Device data transfer failed. len = %d", len);
+
+    return ((len < 0) ? len : ((len != size) ? -EIO : 0));
+}
diff -pruN 3.4.0+dfsg-1/driver/razercommon.h 3.5.1+dfsg-2/driver/razercommon.h
--- 3.4.0+dfsg-1/driver/razercommon.h	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razercommon.h	2022-12-04 11:49:31.000000000 +0000
@@ -9,7 +9,7 @@
 
 #include <linux/usb/input.h>
 
-#define DRIVER_VERSION "3.4.0"
+#define DRIVER_VERSION "3.5.1"
 #define DRIVER_LICENSE "GPL v2"
 #define DRIVER_AUTHOR "Terry Cain <terry@terrys-home.co.uk>"
 
@@ -58,6 +58,12 @@ do { \
 #define BLUE_PROFILE_LED  0x0E
 #define RIGHT_SIDE_LED    0x10
 #define LEFT_SIDE_LED     0x11
+#define ARGB_CH_1_LED     0x1A
+#define ARGB_CH_2_LED     0x1B
+#define ARGB_CH_3_LED     0x1C
+#define ARGB_CH_4_LED     0x1D
+#define ARGB_CH_5_LED     0x1E
+#define ARGB_CH_6_LED     0x1F
 #define CHARGING_LED      0x20
 #define FAST_CHARGING_LED 0x21
 #define FULLY_CHARGED_LED 0x22
@@ -127,6 +133,15 @@ struct razer_report {
     unsigned char reserved; /*0x0*/
 };
 
+struct razer_argb_report {
+    unsigned char report_id;
+    unsigned char channel_1;
+    unsigned char channel_2;
+    unsigned char pad;
+    unsigned char last_idx;
+    unsigned char color_data[315];
+};
+
 struct razer_key_translation {
     u16 from;
     u16 to;
@@ -136,6 +151,7 @@ struct razer_key_translation {
 int razer_send_control_msg(struct usb_device *usb_dev,void const *data, unsigned int report_index, unsigned long wait_min, unsigned long wait_max);
 int razer_send_control_msg_old_device(struct usb_device *usb_dev,void const *data, uint report_value, uint report_index, uint report_size, ulong wait_min, ulong wait_max);
 int razer_get_usb_response(struct usb_device *usb_dev, unsigned int report_index, struct razer_report* request_report, unsigned int response_index, struct razer_report* response_report, unsigned long wait_min, unsigned long wait_max);
+int razer_send_argb_msg(struct usb_device* usb_dev, unsigned char channel, unsigned char size, void const* data);
 unsigned char razer_calculate_crc(struct razer_report *report);
 struct razer_report get_razer_report(unsigned char command_class, unsigned char command_id, unsigned char data_size);
 struct razer_report get_empty_razer_report(void);
diff -pruN 3.4.0+dfsg-1/driver/razerkbd_driver.c 3.5.1+dfsg-2/driver/razerkbd_driver.c
--- 3.4.0+dfsg-1/driver/razerkbd_driver.c	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razerkbd_driver.c	2022-12-04 11:49:31.000000000 +0000
@@ -228,6 +228,7 @@ static bool is_blade_laptop(struct usb_d
     case USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2021:
     case USB_DEVICE_ID_RAZER_BLADE_15_ADV_MID_2021:
     case USB_DEVICE_ID_RAZER_BLADE_15_BASE_EARLY_2021:
+    case USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021:
     case USB_DEVICE_ID_RAZER_BLADE_17_PRO_MID_2021:
     case USB_DEVICE_ID_RAZER_BLADE_14_2021:
     case USB_DEVICE_ID_RAZER_BLADE_17_2022:
@@ -245,11 +246,13 @@ static int razer_get_report(struct usb_d
     uint report_index;
     uint response_index;
     switch (usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report_index = 0x03;
         response_index = 0x03;
         return razer_get_usb_response(usb_dev, report_index, request_report, response_index, response_report, RAZER_BLACKWIDOW_CHROMA_WAIT_MIN_US, RAZER_BLACKWIDOW_CHROMA_WAIT_MAX_US);
@@ -350,6 +353,7 @@ static void razer_set_device_mode(struct
         break;
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report.transaction_id.id = 0x1F;
         break;
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI_WIRELESS:
@@ -515,6 +519,7 @@ static ssize_t razer_attr_write_game_led
     unsigned char enabled = (unsigned char)simple_strtoul(buf, NULL, 10);
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         report = razer_chroma_standard_set_led_state(NOSTORE, GAME_LED, enabled);
         report.transaction_id.id = 0x1f;
@@ -541,6 +546,7 @@ static ssize_t razer_attr_read_game_led_
     struct razer_report response = {0};
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         report = razer_chroma_standard_get_led_state(NOSTORE, GAME_LED);
         report.transaction_id.id = 0x1f;
@@ -565,6 +571,7 @@ static ssize_t razer_attr_write_keyswitc
 
     // Toggle Keyswitch Optimization
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         report = razer_chroma_misc_set_keyswitch_optimization_command1(mode);
         report.transaction_id.id = 0x1f;
@@ -592,6 +599,7 @@ static ssize_t razer_attr_read_keyswitch
     int state;
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         report = razer_chroma_misc_get_keyswitch_optimization();
         report.transaction_id.id = 0x1f;
@@ -822,6 +830,10 @@ static ssize_t razer_attr_read_device_ty
         device_type = "Razer Blade 15 Base (Early 2021)\n";
         break;
 
+    case USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021:
+        device_type = "Razer Blade 17 Pro (Early 2021)\n";
+        break;
+
     case USB_DEVICE_ID_RAZER_BLADE_17_PRO_MID_2021:
         device_type = "Razer Blade 17 Pro (Mid 2021)\n";
         break;
@@ -954,6 +966,10 @@ static ssize_t razer_attr_read_device_ty
         device_type = "Razer BlackWidow V3 Tenkeyless\n";
         break;
 
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
+        device_type = "Razer Huntsman V2 Tenkeyless\n";
+        break;
+
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         device_type = "Razer Huntsman V2\n";
         break;
@@ -982,6 +998,10 @@ static ssize_t razer_attr_read_device_ty
         device_type = "Razer Blade 15 Advanced (Early 2022)\n";
         break;
 
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
+        device_type = "Razer DeathStalker V2\n";
+        break;
+
     default:
         device_type = "Unknown Device\n";
     }
@@ -1325,6 +1345,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report = razer_chroma_extended_matrix_effect_none(VARSTORE, BACKLIGHT_LED);
         break;
 
@@ -1332,6 +1353,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -1394,6 +1416,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report = razer_chroma_extended_matrix_effect_wave(VARSTORE, BACKLIGHT_LED, direction);
         break;
 
@@ -1406,6 +1429,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -1454,12 +1478,14 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report = razer_chroma_extended_matrix_effect_spectrum(VARSTORE, BACKLIGHT_LED);
         break;
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -1531,6 +1557,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report = razer_chroma_extended_matrix_effect_reactive(VARSTORE, BACKLIGHT_LED, speed, (struct razer_rgb*)&buf[1]);
         break;
 
@@ -1538,6 +1565,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -1633,6 +1661,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLADE_PRO_EARLY_2020:
     case USB_DEVICE_ID_RAZER_BLADE_15_ADV_2020:
     case USB_DEVICE_ID_RAZER_BLADE_15_ADV_MID_2021:
+    case USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021:
     case USB_DEVICE_ID_RAZER_BLADE_17_PRO_MID_2021:
     case USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2021:
     case USB_DEVICE_ID_RAZER_BLADE_15_BASE_EARLY_2021:
@@ -1676,6 +1705,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         if (count != 3) {
             printk(KERN_WARNING "razerkbd: Static mode only accepts RGB (3byte)\n");
             return -EINVAL;
@@ -1687,6 +1717,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -1770,6 +1801,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         if(count == 7) {
             report = razer_chroma_extended_matrix_effect_starlight_dual(VARSTORE, BACKLIGHT_LED, buf[0], (struct razer_rgb*)&buf[1], (struct razer_rgb*)&buf[4]);
             razer_send_payload(usb_dev, &report);
@@ -1788,6 +1820,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
         if (count == 7) {
@@ -1839,6 +1872,7 @@ static ssize_t razer_attr_write_matrix_e
         break;
 
     case USB_DEVICE_ID_RAZER_BLADE_STEALTH_LATE_2017:
+    case USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021:
         if(count == 7) {
             report = razer_chroma_standard_matrix_effect_starlight_dual(VARSTORE, BACKLIGHT_LED, buf[0], (struct razer_rgb*)&buf[1], (struct razer_rgb*)&buf[4]);
             razer_send_payload(usb_dev, &report);
@@ -1947,6 +1981,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         switch(count) {
         case 3: // Single colour mode
             report = razer_chroma_extended_matrix_effect_breathing_single(VARSTORE, BACKLIGHT_LED, (struct razer_rgb*)&buf[0]);
@@ -1972,6 +2007,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -2148,6 +2184,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report = razer_chroma_extended_matrix_effect_custom_frame();
         break;
 
@@ -2155,6 +2192,7 @@ static ssize_t razer_attr_write_matrix_e
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -2259,12 +2297,14 @@ static ssize_t razer_attr_write_matrix_b
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report = razer_chroma_extended_matrix_brightness(VARSTORE, BACKLIGHT_LED, brightness);
         break;
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -2336,12 +2376,14 @@ static ssize_t razer_attr_read_matrix_br
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         report = razer_chroma_extended_matrix_get_brightness(VARSTORE, BACKLIGHT_LED);
         break;
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
     case USB_DEVICE_ID_RAZER_ORNATA_V2:
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
         report = razer_chroma_extended_matrix_get_brightness(VARSTORE, BACKLIGHT_LED);
@@ -2481,6 +2523,7 @@ static ssize_t razer_attr_write_matrix_c
         case USB_DEVICE_ID_RAZER_HUNTSMAN:
         case USB_DEVICE_ID_RAZER_CYNOSA_CHROMA:
         case USB_DEVICE_ID_RAZER_CYNOSA_CHROMA_PRO:
+        case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
             report = razer_chroma_extended_matrix_set_custom_frame(row_id, start_col, stop_col, (unsigned char*)&buf[offset]);
             break;
 
@@ -2492,6 +2535,7 @@ static ssize_t razer_attr_write_matrix_c
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
+        case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
@@ -2536,6 +2580,7 @@ static ssize_t razer_attr_write_matrix_c
         case USB_DEVICE_ID_RAZER_BLADE_PRO_EARLY_2020:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_2020:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_MID_2021:
+        case USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021:
         case USB_DEVICE_ID_RAZER_BLADE_17_PRO_MID_2021:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2021:
         case USB_DEVICE_ID_RAZER_BLADE_14_2021:
@@ -2570,6 +2615,7 @@ static ssize_t razer_attr_read_poll_rate
     unsigned short polling_rate = 0;
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         report = razer_chroma_misc_get_polling_rate2();
         report.transaction_id.id = 0x1f;
@@ -2618,6 +2664,7 @@ static ssize_t razer_attr_write_poll_rat
     struct razer_report report = razer_chroma_misc_set_polling_rate(polling_rate);
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
         report = razer_chroma_misc_set_polling_rate2(polling_rate);
         report.transaction_id.id = 0x1f;
@@ -2830,6 +2877,7 @@ static int razer_event(struct hid_device
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
+    case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
         translation = find_translation(chroma_keys_5, usage->code);
         break;
 
@@ -3309,9 +3357,13 @@ static int razer_kbd_probe(struct hid_de
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_macro_led_effect);              // Change macro LED effect (static, flashing)
             break;
 
+        case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_poll_rate);                     // Poll Rate
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_keyswitch_optimization);        // Keyswitch Optimization
+            fallthrough;
+        case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
+        case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_key_super);                     // Super Key
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_key_alt_tab);                   // Alt + Tab
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_key_alt_f4);                    // Alt + F4
@@ -3330,7 +3382,6 @@ static int razer_kbd_probe(struct hid_de
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_ESSENTIAL:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_CHROMA_V2:
         case USB_DEVICE_ID_RAZER_CYNOSA_V2:
-        case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_wave);            // Wave effect
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum);        // Spectrum effect
@@ -3466,6 +3517,7 @@ static int razer_kbd_probe(struct hid_de
         case USB_DEVICE_ID_RAZER_BLADE_PRO_LATE_2019:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_2020:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_MID_2021:
+        case USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021:
         case USB_DEVICE_ID_RAZER_BLADE_17_PRO_MID_2021:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2021:
         case USB_DEVICE_ID_RAZER_BLADE_14_2021:
@@ -3700,9 +3752,13 @@ static void razer_kbd_disconnect(struct
             device_remove_file(&hdev->dev, &dev_attr_macro_led_effect);              // Change macro LED effect (static, flashing)
             break;
 
+        case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
             device_remove_file(&hdev->dev, &dev_attr_poll_rate);                     // Poll Rate
             device_remove_file(&hdev->dev, &dev_attr_keyswitch_optimization);        // Keyswitch Optimization
+            fallthrough;
+        case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
+        case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
             device_remove_file(&hdev->dev, &dev_attr_key_super);                     // Super Key
             device_remove_file(&hdev->dev, &dev_attr_key_alt_tab);                   // Alt + Tab
             device_remove_file(&hdev->dev, &dev_attr_key_alt_f4);                    // Alt + F4
@@ -3721,7 +3777,6 @@ static void razer_kbd_disconnect(struct
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_ESSENTIAL:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_CHROMA_V2:
         case USB_DEVICE_ID_RAZER_CYNOSA_V2:
-        case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
             device_remove_file(&hdev->dev, &dev_attr_matrix_effect_wave);            // Wave effect
             device_remove_file(&hdev->dev, &dev_attr_matrix_effect_spectrum);        // Spectrum effect
@@ -3857,6 +3912,7 @@ static void razer_kbd_disconnect(struct
         case USB_DEVICE_ID_RAZER_BLADE_PRO_LATE_2019:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_2020:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_MID_2021:
+        case USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021:
         case USB_DEVICE_ID_RAZER_BLADE_17_PRO_MID_2021:
         case USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2021:
         case USB_DEVICE_ID_RAZER_BLADE_14_2021:
@@ -3987,17 +4043,20 @@ static const struct hid_device_id razer_
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2021) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_15_ADV_MID_2021) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_15_BASE_EARLY_2021) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_17_PRO_MID_2021) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_14_2021) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_V3) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI_WIRELESS) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_HUNTSMAN_V2) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_17_2022) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2022) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHSTALKER_V2) },
     { 0 }
 };
 
diff -pruN 3.4.0+dfsg-1/driver/razerkbd_driver.h 3.5.1+dfsg-2/driver/razerkbd_driver.h
--- 3.4.0+dfsg-1/driver/razerkbd_driver.h	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razerkbd_driver.h	2022-12-04 11:49:31.000000000 +0000
@@ -76,8 +76,10 @@
 #define USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG 0x0266
 #define USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_JP 0x0269
 #define USB_DEVICE_ID_RAZER_BOOK_2020 0x026A
+#define USB_DEVICE_ID_RAZER_HUNTSMAN_V2_TENKEYLESS 0x026B
 #define USB_DEVICE_ID_RAZER_HUNTSMAN_V2 0x026C
 #define USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2021 0x026D
+#define USB_DEVICE_ID_RAZER_BLADE_17_PRO_EARLY_2021 0x026E
 #define USB_DEVICE_ID_RAZER_BLADE_15_BASE_EARLY_2021 0x026F
 #define USB_DEVICE_ID_RAZER_BLADE_14_2021 0x0270
 #define USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI_WIRELESS 0x0271
@@ -86,6 +88,7 @@
 #define USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG 0x0282
 #define USB_DEVICE_ID_RAZER_BLADE_15_ADV_EARLY_2022 0x028A
 #define USB_DEVICE_ID_RAZER_BLADE_17_2022 0x028B
+#define USB_DEVICE_ID_RAZER_DEATHSTALKER_V2 0x0295
 #define USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK 0x0A24
 
 /* Each keyboard report has 90 bytes*/
diff -pruN 3.4.0+dfsg-1/driver/razermouse_driver.c 3.5.1+dfsg-2/driver/razermouse_driver.c
--- 3.4.0+dfsg-1/driver/razermouse_driver.c	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razermouse_driver.c	2022-12-04 11:49:31.000000000 +0000
@@ -54,6 +54,8 @@ static int razer_get_report(struct usb_d
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         return razer_get_usb_response(usb_dev, index, request_report, index, response_report, RAZER_NEW_MOUSE_RECEIVER_WAIT_MIN_US, RAZER_NEW_MOUSE_RECEIVER_WAIT_MAX_US);
         break;
 
@@ -70,6 +72,7 @@ static int razer_get_report(struct usb_d
         return razer_get_usb_response(usb_dev, index, request_report, index, response_report, RAZER_VIPER_MOUSE_RECEIVER_WAIT_MIN_US, RAZER_VIPER_MOUSE_RECEIVER_WAIT_MAX_US);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_BASILISK_V3:
         index = 0x03;
         return razer_get_usb_response(usb_dev, index, request_report, index, response_report, RAZER_MOUSE_WAIT_MIN_US, RAZER_MOUSE_WAIT_MAX_US);
@@ -314,6 +317,10 @@ static ssize_t razer_attr_read_device_ty
         device_type = "Razer Naga Chroma\n";
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
+        device_type = "Razer Naga X\n";
+        break;
+
     case USB_DEVICE_ID_RAZER_DEATHADDER_ELITE:
         device_type = "Razer DeathAdder Elite\n";
         break;
@@ -450,6 +457,14 @@ static ssize_t razer_attr_read_device_ty
         device_type = "Razer DeathAdder V2 Pro (Wireless)\n";
         break;
 
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+        device_type = "Razer DeathAdder V3 Pro (Wired)\n";
+        break;
+
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+        device_type = "Razer DeathAdder V3 Pro (Wireless)\n";
+        break;
+
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_MINI:
         device_type = "Razer DeathAdder V2 Mini\n";
         break;
@@ -538,6 +553,7 @@ static ssize_t razer_attr_read_firmware_
         return sprintf(buf, "v%d.%d\n", 0x01, 0x00);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -554,6 +570,8 @@ static ssize_t razer_attr_read_firmware_
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
 
@@ -670,6 +688,7 @@ static ssize_t razer_attr_write_matrix_e
         report = razer_chroma_extended_matrix_effect_custom_frame();
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -719,6 +738,7 @@ static ssize_t razer_attr_write_matrix_e
         report.transaction_id.id = 0xff;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -986,8 +1006,14 @@ static ssize_t razer_attr_read_device_se
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
         report.transaction_id.id = 0x1f;
         break;
+
+    case USB_DEVICE_ID_RAZER_NAGA_X:
+        report.transaction_id.id = 0x08;
+        break;
     }
 
     mutex_lock(&device->lock);
@@ -1035,6 +1061,8 @@ static ssize_t razer_attr_read_charge_le
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -1086,6 +1114,8 @@ static ssize_t razer_attr_read_charge_st
     case USB_DEVICE_ID_RAZER_PRO_CLICK_WIRED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -1202,6 +1232,7 @@ static ssize_t razer_attr_read_poll_rate
         report.transaction_id.id = 0x3f;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -1215,6 +1246,8 @@ static ssize_t razer_attr_read_poll_rate
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
         report.transaction_id.id = 0x1f;
         break;
 
@@ -1315,6 +1348,7 @@ static ssize_t razer_attr_write_poll_rat
         report.transaction_id.id = 0x3f;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -1330,6 +1364,8 @@ static ssize_t razer_attr_write_poll_rat
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
         report.transaction_id.id = 0x1f;
         break;
 
@@ -1374,6 +1410,7 @@ static ssize_t razer_attr_write_matrix_b
         report.transaction_id.id = 0x3f;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -1427,6 +1464,7 @@ static ssize_t razer_attr_read_matrix_br
         report.transaction_id.id = 0x3f;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -1525,6 +1563,7 @@ static ssize_t razer_attr_write_dpi(stru
         return count;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -1575,6 +1614,7 @@ static ssize_t razer_attr_write_dpi(stru
         report.transaction_id.id = 0x3f;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -1591,6 +1631,8 @@ static ssize_t razer_attr_write_dpi(stru
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -1648,6 +1690,7 @@ static ssize_t razer_attr_read_dpi(struc
         report = razer_chroma_misc_get_dpi_xy_byte();
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -1664,6 +1707,8 @@ static ssize_t razer_attr_read_dpi(struc
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report = razer_chroma_misc_get_dpi_xy(NOSTORE);
         report.transaction_id.id = 0x1f;
         break;
@@ -1971,6 +2016,8 @@ static ssize_t razer_attr_write_dpi_stag
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -2021,6 +2068,8 @@ static ssize_t razer_attr_read_dpi_stage
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -2083,6 +2132,8 @@ static ssize_t razer_attr_read_device_id
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -2111,6 +2162,8 @@ static ssize_t razer_attr_write_device_i
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -2262,6 +2315,7 @@ static ssize_t razer_attr_write_matrix_c
             report = razer_chroma_misc_one_row_set_custom_frame(start_col, stop_col, (unsigned char*)&buf[offset]);
             break;
 
+        case USB_DEVICE_ID_RAZER_NAGA_X:
         case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
         case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
         case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2302,6 +2356,7 @@ static ssize_t razer_attr_write_device_m
         return count;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2318,6 +2373,8 @@ static ssize_t razer_attr_write_device_m
     case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
 
@@ -2383,6 +2440,7 @@ static ssize_t razer_attr_read_device_mo
         report.transaction_id.id = 0x3f;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2398,6 +2456,8 @@ static ssize_t razer_attr_read_device_mo
     case USB_DEVICE_ID_RAZER_PRO_CLICK_WIRED:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
     case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
+    case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
         report.transaction_id.id = 0x1f;
         break;
     }
@@ -2428,6 +2488,7 @@ static ssize_t razer_attr_read_scroll_le
         report.transaction_id.id = 0x3F;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2481,6 +2542,7 @@ static ssize_t razer_attr_write_scroll_l
         report.transaction_id.id = 0x3F;
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2535,6 +2597,7 @@ static ssize_t razer_attr_read_logo_led_
         break;
 
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2600,6 +2663,7 @@ static ssize_t razer_attr_write_logo_led
         break;
 
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2664,6 +2728,7 @@ static ssize_t razer_attr_read_side_led_
         report = razer_chroma_extended_matrix_get_brightness(VARSTORE, side);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -2700,6 +2765,7 @@ static ssize_t razer_attr_write_side_led
         report = razer_chroma_extended_matrix_brightness(VARSTORE, side, brightness);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3142,6 +3208,7 @@ static ssize_t razer_attr_write_scroll_m
         report = razer_chroma_extended_matrix_effect_wave(VARSTORE, SCROLL_WHEEL_LED, direction);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3191,6 +3258,7 @@ static ssize_t razer_attr_write_scroll_m
         report = razer_chroma_extended_matrix_effect_spectrum(VARSTORE, SCROLL_WHEEL_LED);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3251,6 +3319,7 @@ static ssize_t razer_attr_write_scroll_m
         report = razer_chroma_extended_matrix_effect_reactive(VARSTORE, SCROLL_WHEEL_LED, speed, (struct razer_rgb*)&buf[1]);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3302,6 +3371,7 @@ static ssize_t razer_attr_write_scroll_m
         }
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3338,6 +3408,7 @@ static ssize_t razer_attr_write_scroll_m
     }
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3394,6 +3465,7 @@ static ssize_t razer_attr_write_scroll_m
         report = razer_chroma_extended_matrix_effect_static(VARSTORE, SCROLL_WHEEL_LED, (struct razer_rgb*)&buf[0]);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3450,6 +3522,7 @@ static ssize_t razer_attr_write_scroll_m
         report = razer_chroma_extended_matrix_effect_none(VARSTORE, SCROLL_WHEEL_LED);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3492,6 +3565,7 @@ static ssize_t razer_attr_write_logo_mat
         report = razer_chroma_extended_matrix_effect_wave(VARSTORE, LOGO_LED, direction);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3551,6 +3625,7 @@ static ssize_t razer_attr_write_logo_mat
         break;
 
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3621,6 +3696,7 @@ static ssize_t razer_attr_write_logo_mat
         break;
 
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3673,6 +3749,7 @@ static ssize_t razer_attr_write_logo_mat
         break;
 
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3721,6 +3798,7 @@ static ssize_t razer_attr_write_logo_mat
 
     switch(usb_dev->descriptor.idProduct) {
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3789,6 +3867,7 @@ static ssize_t razer_attr_write_logo_mat
         break;
 
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3855,6 +3934,7 @@ static ssize_t razer_attr_write_logo_mat
         break;
 
     case USB_DEVICE_ID_RAZER_VIPER_8K:
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3892,6 +3972,7 @@ static ssize_t razer_attr_write_side_mod
         report = razer_chroma_extended_matrix_effect_wave(VARSTORE, side, direction);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -3947,6 +4028,7 @@ static ssize_t razer_attr_write_side_mod
         report = razer_chroma_extended_matrix_effect_spectrum(VARSTORE, side);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -4009,6 +4091,7 @@ static ssize_t razer_attr_write_side_mod
         report = razer_chroma_extended_matrix_effect_reactive(VARSTORE, side, speed, (struct razer_rgb*)&buf[1]);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -4056,6 +4139,7 @@ static ssize_t razer_attr_write_side_mod
     struct razer_report report = {0};
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -4084,6 +4168,7 @@ static ssize_t razer_attr_write_side_mod
     }
 
     switch(usb_dev->descriptor.idProduct) {
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -4142,6 +4227,7 @@ static ssize_t razer_attr_write_side_mod
         report = razer_chroma_extended_matrix_effect_static(VARSTORE, side, (struct razer_rgb*)&buf[0]);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -4193,6 +4279,7 @@ static ssize_t razer_attr_write_side_mod
         report = razer_chroma_extended_matrix_effect_none(VARSTORE, side);
         break;
 
+    case USB_DEVICE_ID_RAZER_NAGA_X:
     case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED:
     case USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS:
@@ -4828,6 +4915,7 @@ static int razer_mouse_probe(struct hid_
         case USB_DEVICE_ID_RAZER_LANCEHEAD_TE_WIRED:
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_poll_rate);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi_stages);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_led_brightness);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_matrix_effect_wave);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_matrix_effect_spectrum);
@@ -5215,7 +5303,6 @@ static int razer_mouse_probe(struct hid_
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_reactive);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_breath);
-            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_led_state);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_none);
             break;
 
@@ -5232,6 +5319,31 @@ static int razer_mouse_probe(struct hid_
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi);
             break;
 
+        case USB_DEVICE_ID_RAZER_NAGA_X:
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi_stages);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_poll_rate);
+
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_scroll_led_brightness);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_scroll_matrix_effect_wave);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_scroll_matrix_effect_spectrum);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_scroll_matrix_effect_reactive);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_scroll_matrix_effect_breath);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_scroll_matrix_effect_static);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_scroll_matrix_effect_none);
+
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_left_led_brightness);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_left_matrix_effect_wave);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_left_matrix_effect_spectrum);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_left_matrix_effect_reactive);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_left_matrix_effect_breath);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_left_matrix_effect_static);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_left_matrix_effect_none);
+
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame);
+            break;
+
         case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_poll_rate);
@@ -5422,6 +5534,7 @@ static int razer_mouse_probe(struct hid_
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_poll_rate);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_idle_time);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi);
+            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi_stages);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_led_brightness);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_matrix_effect_spectrum);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_matrix_effect_reactive);
@@ -5441,6 +5554,8 @@ static int razer_mouse_probe(struct hid_
         case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
         case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
         case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
+        case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+        case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_poll_rate);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi);
             CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_dpi_stages);
@@ -5538,6 +5653,7 @@ static void razer_mouse_disconnect(struc
         case USB_DEVICE_ID_RAZER_LANCEHEAD_TE_WIRED:
             device_remove_file(&hdev->dev, &dev_attr_poll_rate);
             device_remove_file(&hdev->dev, &dev_attr_dpi);
+            device_remove_file(&hdev->dev, &dev_attr_dpi_stages);
             device_remove_file(&hdev->dev, &dev_attr_logo_led_brightness);
             device_remove_file(&hdev->dev, &dev_attr_logo_matrix_effect_wave);
             device_remove_file(&hdev->dev, &dev_attr_logo_matrix_effect_spectrum);
@@ -5904,7 +6020,6 @@ static void razer_mouse_disconnect(struc
             device_remove_file(&hdev->dev, &dev_attr_matrix_effect_spectrum);
             device_remove_file(&hdev->dev, &dev_attr_matrix_effect_reactive);
             device_remove_file(&hdev->dev, &dev_attr_matrix_effect_breath);
-            device_remove_file(&hdev->dev, &dev_attr_logo_led_state);
             device_remove_file(&hdev->dev, &dev_attr_matrix_effect_none);
             break;
 
@@ -5921,6 +6036,31 @@ static void razer_mouse_disconnect(struc
             device_remove_file(&hdev->dev, &dev_attr_dpi);
             break;
 
+        case USB_DEVICE_ID_RAZER_NAGA_X:
+            device_remove_file(&hdev->dev, &dev_attr_dpi);
+            device_remove_file(&hdev->dev, &dev_attr_dpi_stages);
+            device_remove_file(&hdev->dev, &dev_attr_poll_rate);
+
+            device_remove_file(&hdev->dev, &dev_attr_scroll_led_brightness);
+            device_remove_file(&hdev->dev, &dev_attr_scroll_matrix_effect_wave);
+            device_remove_file(&hdev->dev, &dev_attr_scroll_matrix_effect_spectrum);
+            device_remove_file(&hdev->dev, &dev_attr_scroll_matrix_effect_reactive);
+            device_remove_file(&hdev->dev, &dev_attr_scroll_matrix_effect_breath);
+            device_remove_file(&hdev->dev, &dev_attr_scroll_matrix_effect_static);
+            device_remove_file(&hdev->dev, &dev_attr_scroll_matrix_effect_none);
+
+            device_remove_file(&hdev->dev, &dev_attr_left_led_brightness);
+            device_remove_file(&hdev->dev, &dev_attr_left_matrix_effect_wave);
+            device_remove_file(&hdev->dev, &dev_attr_left_matrix_effect_spectrum);
+            device_remove_file(&hdev->dev, &dev_attr_left_matrix_effect_reactive);
+            device_remove_file(&hdev->dev, &dev_attr_left_matrix_effect_breath);
+            device_remove_file(&hdev->dev, &dev_attr_left_matrix_effect_static);
+            device_remove_file(&hdev->dev, &dev_attr_left_matrix_effect_none);
+
+            device_remove_file(&hdev->dev, &dev_attr_matrix_effect_custom);
+            device_remove_file(&hdev->dev, &dev_attr_matrix_custom_frame);
+            break;
+
         case USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020:
             device_remove_file(&hdev->dev, &dev_attr_dpi);
             device_remove_file(&hdev->dev, &dev_attr_poll_rate);
@@ -6111,6 +6251,7 @@ static void razer_mouse_disconnect(struc
             device_remove_file(&hdev->dev, &dev_attr_poll_rate);
             device_remove_file(&hdev->dev, &dev_attr_device_idle_time);
             device_remove_file(&hdev->dev, &dev_attr_dpi);
+            device_remove_file(&hdev->dev, &dev_attr_dpi_stages);
             device_remove_file(&hdev->dev, &dev_attr_logo_led_brightness);
             device_remove_file(&hdev->dev, &dev_attr_logo_matrix_effect_spectrum);
             device_remove_file(&hdev->dev, &dev_attr_logo_matrix_effect_reactive);
@@ -6130,6 +6271,8 @@ static void razer_mouse_disconnect(struc
         case USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED:
         case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED:
         case USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS:
+        case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED:
+        case USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS:
             device_remove_file(&hdev->dev, &dev_attr_poll_rate);
             device_remove_file(&hdev->dev, &dev_attr_dpi);
             device_remove_file(&hdev->dev, &dev_attr_dpi_stages);
@@ -6230,6 +6373,7 @@ static const struct hid_device_id razer_
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHADDER_2000) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_ATHERIS_RECEIVER) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BASILISK_X_HYPERSPEED) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_NAGA_X) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_NAGA_LEFT_HANDED_2020) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_NAGA_PRO_WIRED) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_NAGA_PRO_WIRELESS) },
@@ -6240,6 +6384,8 @@ static const struct hid_device_id razer_
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_PRO_CLICK_WIRED) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS) },
     { 0 }
 };
 
diff -pruN 3.4.0+dfsg-1/driver/razermouse_driver.h 3.5.1+dfsg-2/driver/razermouse_driver.h
--- 3.4.0+dfsg-1/driver/razermouse_driver.h	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/driver/razermouse_driver.h	2022-12-04 11:49:31.000000000 +0000
@@ -74,11 +74,14 @@
 #define USB_DEVICE_ID_RAZER_VIPER_8K 0x0091
 #define USB_DEVICE_ID_RAZER_OROCHI_V2_RECEIVER 0x0094
 #define USB_DEVICE_ID_RAZER_OROCHI_V2_BLUETOOTH 0x0095
+#define USB_DEVICE_ID_RAZER_NAGA_X 0x0096
 #define USB_DEVICE_ID_RAZER_DEATHADDER_ESSENTIAL_2021 0x0098
 #define USB_DEVICE_ID_RAZER_BASILISK_V3 0x0099
 #define USB_DEVICE_ID_RAZER_DEATHADDER_V2_X_HYPERSPEED 0x009C
 #define USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRED 0x00A5
 #define USB_DEVICE_ID_RAZER_VIPER_V2_PRO_WIRELESS 0x00A6
+#define USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRED 0x00B6
+#define USB_DEVICE_ID_RAZER_DEATHADDER_V3_PRO_WIRELESS 0x00B7
 
 /* Each keyboard report has 90 bytes*/
 #define RAZER_REPORT_LEN 0x5A
diff -pruN 3.4.0+dfsg-1/.github/ISSUE_TEMPLATE/new-device-support.md 3.5.1+dfsg-2/.github/ISSUE_TEMPLATE/new-device-support.md
--- 3.4.0+dfsg-1/.github/ISSUE_TEMPLATE/new-device-support.md	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/.github/ISSUE_TEMPLATE/new-device-support.md	2022-12-04 11:49:31.000000000 +0000
@@ -24,6 +24,15 @@ Please post the output of
     ls -lah /dev/input/by-id/
 ```
 
+<details>
+
+```
+Please post the output of
+    usbhid-dump -m 1532 -ed
+```
+
+</details>
+
 ### Packet Captures
 
 <Please see here as we probably need packet captures>
diff -pruN 3.4.0+dfsg-1/.github/workflows/stale.yml 3.5.1+dfsg-2/.github/workflows/stale.yml
--- 3.4.0+dfsg-1/.github/workflows/stale.yml	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/.github/workflows/stale.yml	2022-12-04 11:49:31.000000000 +0000
@@ -13,11 +13,14 @@ jobs:
       pull-requests: write
 
     steps:
-    - uses: actions/stale@v3
+    - uses: actions/stale@v5.1.1
       with:
         repo-token: ${{ secrets.GITHUB_TOKEN }}
         stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
         days-before-issue-stale: 120
         days-before-issue-close: 30
+        days-before-pr-stale: -1
+        days-before-pr-close: -1
         stale-issue-label: 'wontfix'
         exempt-issue-labels: 'Device Support,not stale'
+        close-issue-reason: 'not_planned'
diff -pruN 3.4.0+dfsg-1/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml 3.5.1+dfsg-2/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml
--- 3.4.0+dfsg-1/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml	2022-12-04 11:49:31.000000000 +0000
@@ -85,11 +85,14 @@
     <modalias>usb:v1532p0091d*</modalias>
     <modalias>usb:v1532p0094d*</modalias>
     <modalias>usb:v1532p0095d*</modalias>
+    <modalias>usb:v1532p0096d*</modalias>
     <modalias>usb:v1532p0098d*</modalias>
     <modalias>usb:v1532p0099d*</modalias>
     <modalias>usb:v1532p009Cd*</modalias>
     <modalias>usb:v1532p00A5d*</modalias>
     <modalias>usb:v1532p00A6d*</modalias>
+    <modalias>usb:v1532p00B6d*</modalias>
+    <modalias>usb:v1532p00B7d*</modalias>
     <modalias>usb:v1532p010Dd*</modalias>
     <modalias>usb:v1532p010Ed*</modalias>
     <modalias>usb:v1532p010Fd*</modalias>
@@ -159,8 +162,10 @@
     <modalias>usb:v1532p0266d*</modalias>
     <modalias>usb:v1532p0269d*</modalias>
     <modalias>usb:v1532p026Ad*</modalias>
+    <modalias>usb:v1532p026Bd*</modalias>
     <modalias>usb:v1532p026Cd*</modalias>
     <modalias>usb:v1532p026Dd*</modalias>
+    <modalias>usb:v1532p026Ed*</modalias>
     <modalias>usb:v1532p026Fd*</modalias>
     <modalias>usb:v1532p0270d*</modalias>
     <modalias>usb:v1532p0271d*</modalias>
@@ -169,6 +174,7 @@
     <modalias>usb:v1532p0282d*</modalias>
     <modalias>usb:v1532p028Ad*</modalias>
     <modalias>usb:v1532p028Bd*</modalias>
+    <modalias>usb:v1532p0295d*</modalias>
     <modalias>usb:v1532p0501d*</modalias>
     <modalias>usb:v1532p0504d*</modalias>
     <modalias>usb:v1532p0506d*</modalias>
@@ -187,6 +193,7 @@
     <modalias>usb:v1532p0F12d*</modalias>
     <modalias>usb:v1532p0F19d*</modalias>
     <modalias>usb:v1532p0F1Dd*</modalias>
+    <modalias>usb:v1532p0F1Fd*</modalias>
     <modalias>usb:v1532p0F20d*</modalias>
     <modalias>usb:v1532p0F21d*</modalias>
     <modalias>usb:v1532p0F26d*</modalias>
diff -pruN 3.4.0+dfsg-1/install_files/dkms/dkms.conf 3.5.1+dfsg-2/install_files/dkms/dkms.conf
--- 3.4.0+dfsg-1/install_files/dkms/dkms.conf	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/install_files/dkms/dkms.conf	2022-12-04 11:49:31.000000000 +0000
@@ -1,5 +1,5 @@
 PACKAGE_NAME="openrazer-driver"
-PACKAGE_VERSION="3.4.0"
+PACKAGE_VERSION="3.5.1"
 AUTOINSTALL="yes"
 MAKE="KERNELDIR=/lib/modules/${kernelver}/build make driver"
 
diff -pruN 3.4.0+dfsg-1/install_files/udev/99-razer.rules 3.5.1+dfsg-2/install_files/udev/99-razer.rules
--- 3.4.0+dfsg-1/install_files/udev/99-razer.rules	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/install_files/udev/99-razer.rules	2022-12-04 11:49:31.000000000 +0000
@@ -5,12 +5,12 @@ GOTO="razer_end"
 LABEL="razer_vendor"
 
 # Mice
-ATTRS{idProduct}=="0013|0016|0020|0024|0025|0029|002e|002f|0032|0034|0036|0037|0038|0039|003e|003f|0040|0041|0042|0043|0044|0045|0046|0048|004c|004f|0050|0053|0054|0059|005a|005b|005c|005e|0060|0062|0064|0065|0067|006a|006b|006c|006e|006f|0070|0071|0072|0073|0077|0078|007a|007b|007c|007d|0080|0083|0084|0085|0086|0088|008a|008c|008d|008f|0090|0091|0094|0095|0098|0099|009c|00a5|00a6", \
+ATTRS{idProduct}=="0013|0016|0020|0024|0025|0029|002e|002f|0032|0034|0036|0037|0038|0039|003e|003f|0040|0041|0042|0043|0044|0045|0046|0048|004c|004f|0050|0053|0054|0059|005a|005b|005c|005e|0060|0062|0064|0065|0067|006a|006b|006c|006e|006f|0070|0071|0072|0073|0077|0078|007a|007b|007c|007d|0080|0083|0084|0085|0086|0088|008a|008c|008d|008f|0090|0091|0094|0095|0096|0098|0099|009c|00a5|00a6|00b6|00b7", \
     ATTRS{idVendor}=="1532", \
     ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razermouse"
 
 # Keyboards
-ATTRS{idProduct}=="010d|010e|010f|0111|0113|011a|011b|011c|0201|0202|0203|0204|0205|0207|0208|0209|020f|0210|0211|0214|0216|0217|021a|021e|021f|0220|0221|0224|0225|0226|0227|0228|022a|022b|022c|022d|022f|0232|0233|0234|0235|0237|0239|023a|023b|023f|0240|0241|0243|0245|0246|024a|024c|024d|024e|0252|0253|0255|0256|0257|0258|0259|025a|025d|025e|0266|0269|026a|026c|026d|026f|0270|0271|0276|0279|0282|028a|028b|0a24", \
+ATTRS{idProduct}=="010d|010e|010f|0111|0113|011a|011b|011c|0201|0202|0203|0204|0205|0207|0208|0209|020f|0210|0211|0214|0216|0217|021a|021e|021f|0220|0221|0224|0225|0226|0227|0228|022a|022b|022c|022d|022f|0232|0233|0234|0235|0237|0239|023a|023b|023f|0240|0241|0243|0245|0246|024a|024c|024d|024e|0252|0253|0255|0256|0257|0258|0259|025a|025d|025e|0266|0269|026a|026b|026c|026d|026e|026f|0270|0271|0276|0279|0282|028a|028b|0295|0a24", \
     ATTRS{idVendor}=="1532", \
     ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razerkbd"
 
@@ -20,7 +20,7 @@ ATTRS{idProduct}=="0501|0504|0506|0510|0
     ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razerkraken"
 
 # Accessories (Speakers, Mousemats, Razer Core, etc)
-ATTRS{idProduct}=="0068|007e|0215|0517|0518|0c00|0c01|0c02|0c04|0f07|0f08|0f09|0f12|0f19|0f1d|0f20|0f21|0f26", \
+ATTRS{idProduct}=="0068|007e|0215|0517|0518|0c00|0c01|0c02|0c04|0f07|0f08|0f09|0f12|0f19|0f1d|0f1f|0f20|0f21|0f26", \
     ATTRS{idVendor}=="1532", \
     ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razeraccessory"
 
diff -pruN 3.4.0+dfsg-1/Makefile 3.5.1+dfsg-2/Makefile
--- 3.4.0+dfsg-1/Makefile	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/Makefile	2022-12-04 11:49:31.000000000 +0000
@@ -28,7 +28,7 @@ MODULEDIR?=/lib/modules/$(shell uname -r
 PYTHONDIR?=$(shell python3 -c 'import sys; print(sys.path[-1])')
 
 DKMS_NAME?=openrazer-driver
-DKMS_VER?=3.4.0
+DKMS_VER?=3.5.1
 
 
 # Build all target
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/client/devices/__init__.py 3.5.1+dfsg-2/pylib/openrazer/client/devices/__init__.py
--- 3.4.0+dfsg-1/pylib/openrazer/client/devices/__init__.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/client/devices/__init__.py	2022-12-04 11:49:31.000000000 +0000
@@ -67,6 +67,7 @@ class RazerDevice(object):
             'macro_mode_led': self._has_feature('razer.device.led.macromode', 'setMacroMode'),
             'macro_mode_led_effect': self._has_feature('razer.device.led.macromode', 'setMacroEffect'),
             'macro_mode_modifier': self._has_feature('razer.device.macro', 'setModeModifier'),
+            'reactive_trigger': self._has_feature('razer.device.misc', 'triggerReactive'),
 
             'poll_rate': self._has_feature('razer.device.misc', ('getPollRate', 'setPollRate')),
             'supported_poll_rates': self._has_feature('razer.device.misc', 'getSupportedPollRates'),
@@ -88,6 +89,7 @@ class RazerDevice(object):
             'lighting_none': self._has_feature('razer.device.lighting.chroma', 'setNone'),
             'lighting_spectrum': self._has_feature('razer.device.lighting.chroma', 'setSpectrum'),
             'lighting_static': self._has_feature('razer.device.lighting.chroma', 'setStatic'),
+            'lighting_blinking': self._has_feature('razer.device.lighting.chroma', 'setBlinking'),
 
             'lighting_starlight_single': self._has_feature('razer.device.lighting.chroma', 'setStarlightSingle'),
             'lighting_starlight_dual': self._has_feature('razer.device.lighting.chroma', 'setStarlightDual'),
@@ -516,8 +518,8 @@ class RazerDevice(object):
         if self.has('poll_rate'):
             if not isinstance(poll_rate, int):
                 raise ValueError("Poll rate is not an integer: {0}".format(poll_rate))
-            if poll_rate not in (_c.POLL_125HZ, _c.POLL_500HZ, _c.POLL_1000HZ, _c.POLL_2000HZ, _c.POLL_4000HZ, _c.POLL_8000HZ):
-                raise ValueError('Poll rate "{0}" is not one of {1}'.format(poll_rate, (_c.POLL_125HZ, _c.POLL_500HZ, _c.POLL_1000HZ, _c.POLL_2000HZ, _c.POLL_4000HZ, _c.POLL_8000HZ)))
+            if poll_rate not in (_c.POLL_125HZ, _c.POLL_250HZ, _c.POLL_500HZ, _c.POLL_1000HZ, _c.POLL_2000HZ, _c.POLL_4000HZ, _c.POLL_8000HZ):
+                raise ValueError('Poll rate "{0}" is not one of {1}'.format(poll_rate, (_c.POLL_125HZ, _c.POLL_250HZ, _c.POLL_500HZ, _c.POLL_1000HZ, _c.POLL_2000HZ, _c.POLL_4000HZ, _c.POLL_8000HZ)))
 
             self._dbus_interfaces['device'].setPollRate(poll_rate)
 
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/client/__init__.py 3.5.1+dfsg-2/pylib/openrazer/client/__init__.py
--- 3.4.0+dfsg-1/pylib/openrazer/client/__init__.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/client/__init__.py	2022-12-04 11:49:31.000000000 +0000
@@ -5,7 +5,7 @@ import dbus as _dbus
 from openrazer.client.device import RazerDeviceFactory as _RazerDeviceFactory
 from openrazer.client import constants
 
-__version__ = '3.4.0'
+__version__ = '3.5.1'
 
 
 class DaemonNotFound(Exception):
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerblackwidowv3.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerblackwidowv3.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerblackwidowv3.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerblackwidowv3.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -9,6 +9,9 @@ files = rw,device_mode,0x0000
         r,firmware_version,v1.0
         rw,game_led_state,0
         r,kbd_layout,01
+        rw,key_alt_f4,0x00
+        rw,key_alt_tab,0x00
+        rw,key_super,0x00
         rw,macro_led_effect,0
         rw,macro_led_state,0
         rw,matrix_brightness,0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerblade17proearly2021.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerblade17proearly2021.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerblade17proearly2021.cfg	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerblade17proearly2021.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,22 @@
+# DO NOT EDIT THIS FILE!
+# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
+[device]
+dir_name = 0003:1532:026E.0001
+name = Razer Blade 17 Pro (Early 2021)
+files = rw,device_mode,0x0000
+        r,device_serial,XX000000026E
+        r,device_type,%(name)s
+        r,firmware_version,v1.0
+        r,kbd_layout,01
+        rw,logo_led_state,0
+        rw,matrix_brightness,0
+        w,matrix_custom_frame
+        w,matrix_effect_breath
+        w,matrix_effect_custom
+        w,matrix_effect_none
+        w,matrix_effect_reactive
+        w,matrix_effect_spectrum
+        w,matrix_effect_starlight
+        w,matrix_effect_static
+        w,matrix_effect_wave
+        r,version,1.0.0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerchromaaddressablergbcontroller.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerchromaaddressablergbcontroller.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerchromaaddressablergbcontroller.cfg	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerchromaaddressablergbcontroller.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,31 @@
+# DO NOT EDIT THIS FILE!
+# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
+[device]
+dir_name = 0003:1532:0F1F.0001
+name = Razer Chroma Addressable RGB Controller
+files = rw,channel1_led_brightness,0
+        rw,channel1_size,8
+        rw,channel2_led_brightness,0
+        rw,channel2_size,8
+        rw,channel3_led_brightness,0
+        rw,channel3_size,8
+        rw,channel4_led_brightness,0
+        rw,channel4_size,8
+        rw,channel5_led_brightness,0
+        rw,channel5_size,8
+        rw,channel6_led_brightness,0
+        rw,channel6_size,8
+        rw,device_mode,0x0000
+        r,device_serial,XX0000000F1F
+        r,device_type,%(name)s
+        r,firmware_version,v1.0
+        rw,matrix_brightness,0
+        w,matrix_custom_frame
+        w,matrix_effect_breath
+        w,matrix_effect_custom
+        w,matrix_effect_none
+        w,matrix_effect_spectrum
+        w,matrix_effect_static
+        w,matrix_effect_wave
+        w,reset_channels,1
+        r,version,1.0.0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv2prowired.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv2prowired.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv2prowired.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv2prowired.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -11,6 +11,7 @@ files = r,charge_level,255
         r,device_serial,XX000000007C
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,logo_led_brightness,0
         w,logo_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv2prowireless.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv2prowireless.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv2prowireless.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv2prowireless.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -13,6 +13,7 @@ files = w,charge_colour
         r,device_serial,XX000000007D
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,logo_led_brightness,0
         w,logo_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv3prowired.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv3prowired.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv3prowired.cfg	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv3prowired.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,17 @@
+# DO NOT EDIT THIS FILE!
+# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
+[device]
+dir_name = 0003:1532:00B6.0001
+name = Razer DeathAdder V3 Pro (Wired)
+files = r,charge_level,255
+        rw,charge_low_threshold,38
+        r,charge_status,1
+        rw,device_idle_time,600
+        rw,device_mode,0x0000
+        r,device_serial,XX00000000B6
+        r,device_type,%(name)s
+        rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
+        r,firmware_version,v1.0
+        rw,poll_rate,500
+        r,version,1.0.0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv3prowireless.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv3prowireless.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathadderv3prowireless.cfg	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathadderv3prowireless.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,17 @@
+# DO NOT EDIT THIS FILE!
+# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
+[device]
+dir_name = 0003:1532:00B7.0001
+name = Razer DeathAdder V3 Pro (Wireless)
+files = r,charge_level,255
+        rw,charge_low_threshold,38
+        r,charge_status,1
+        rw,device_idle_time,600
+        rw,device_mode,0x0000
+        r,device_serial,XX00000000B7
+        r,device_type,%(name)s
+        rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
+        r,firmware_version,v1.0
+        rw,poll_rate,500
+        r,version,1.0.0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathstalkerv2.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathstalkerv2.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdeathstalkerv2.cfg	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdeathstalkerv2.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,27 @@
+# DO NOT EDIT THIS FILE!
+# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
+[device]
+dir_name = 0003:1532:0295.0001
+name = Razer DeathStalker V2
+files = rw,device_mode,0x0000
+        r,device_serial,XX0000000295
+        r,device_type,%(name)s
+        r,firmware_version,v1.0
+        rw,game_led_state,0
+        r,kbd_layout,01
+        rw,key_alt_f4,0x00
+        rw,key_alt_tab,0x00
+        rw,key_super,0x00
+        rw,macro_led_effect,0
+        rw,macro_led_state,0
+        rw,matrix_brightness,0
+        w,matrix_custom_frame
+        w,matrix_effect_breath
+        w,matrix_effect_custom
+        w,matrix_effect_none
+        w,matrix_effect_reactive
+        w,matrix_effect_spectrum
+        w,matrix_effect_starlight
+        w,matrix_effect_static
+        w,matrix_effect_wave
+        r,version,1.0.0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdiamondbackchroma.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdiamondbackchroma.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerdiamondbackchroma.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerdiamondbackchroma.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -8,7 +8,6 @@ files = rw,device_mode,0x0000
         r,device_type,%(name)s
         rw,dpi,800:800
         r,firmware_version,v1.0
-        rw,logo_led_state,0
         rw,matrix_brightness,0
         w,matrix_custom_frame
         w,matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerhuntsmanv2.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerhuntsmanv2.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerhuntsmanv2.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerhuntsmanv2.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -9,6 +9,7 @@ files = rw,device_mode,0x0000
         r,firmware_version,v1.0
         rw,game_led_state,0
         r,kbd_layout,01
+        rw,key_alt_f4,0x00
         rw,key_alt_tab,0x00
         rw,key_super,0x00
         rw,keyswitch_optimization,0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerhuntsmanv2tenkeyless.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerhuntsmanv2tenkeyless.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerhuntsmanv2tenkeyless.cfg	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerhuntsmanv2tenkeyless.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,29 @@
+# DO NOT EDIT THIS FILE!
+# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
+[device]
+dir_name = 0003:1532:026B.0001
+name = Razer Huntsman V2 Tenkeyless
+files = rw,device_mode,0x0000
+        r,device_serial,XX000000026B
+        r,device_type,%(name)s
+        r,firmware_version,v1.0
+        rw,game_led_state,0
+        r,kbd_layout,01
+        rw,key_alt_f4,0x00
+        rw,key_alt_tab,0x00
+        rw,key_super,0x00
+        rw,keyswitch_optimization,0
+        rw,macro_led_effect,0
+        rw,macro_led_state,0
+        rw,matrix_brightness,0
+        w,matrix_custom_frame
+        w,matrix_effect_breath
+        w,matrix_effect_custom
+        w,matrix_effect_none
+        w,matrix_effect_reactive
+        w,matrix_effect_spectrum
+        w,matrix_effect_starlight
+        w,matrix_effect_static
+        w,matrix_effect_wave
+        rw,poll_rate,500
+        r,version,1.0.0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadtournamentedition.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadtournamentedition.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadtournamentedition.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadtournamentedition.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -7,6 +7,7 @@ files = rw,device_mode,0x0000
         r,device_serial,XX0000000060
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,left_led_brightness,0
         w,left_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwired.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwired.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwired.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwired.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -11,6 +11,7 @@ files = r,charge_level,255
         r,device_serial,XX0000000059
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,left_led_brightness,0
         w,left_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwireless.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwireless.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwireless.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwireless.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -13,6 +13,7 @@ files = w,charge_colour
         r,device_serial,XX000000005A
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,left_led_brightness,0
         w,left_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwirelessreceiver.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwirelessreceiver.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwirelessreceiver.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwirelessreceiver.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -13,6 +13,7 @@ files = w,charge_colour
         r,device_serial,XX000000006F
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,left_led_brightness,0
         w,left_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwirelesswired.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwirelesswired.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerlanceheadwirelesswired.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerlanceheadwirelesswired.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -11,6 +11,7 @@ files = r,charge_level,255
         r,device_serial,XX0000000070
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,left_led_brightness,0
         w,left_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razernagax.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razernagax.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razernagax.cfg	1970-01-01 00:00:00.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razernagax.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -0,0 +1,29 @@
+# DO NOT EDIT THIS FILE!
+# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
+[device]
+dir_name = 0003:1532:0096.0001
+name = Razer Naga X
+files = rw,device_mode,0x0000
+        r,device_serial,XX0000000096
+        r,device_type,%(name)s
+        rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
+        r,firmware_version,v1.0
+        rw,left_led_brightness,0
+        w,left_matrix_effect_breath
+        w,left_matrix_effect_none
+        w,left_matrix_effect_reactive
+        w,left_matrix_effect_spectrum
+        w,left_matrix_effect_static
+        w,left_matrix_effect_wave
+        w,matrix_custom_frame
+        w,matrix_effect_custom
+        rw,poll_rate,500
+        rw,scroll_led_brightness,0
+        w,scroll_matrix_effect_breath
+        w,scroll_matrix_effect_none
+        w,scroll_matrix_effect_reactive
+        w,scroll_matrix_effect_spectrum
+        w,scroll_matrix_effect_static
+        w,scroll_matrix_effect_wave
+        r,version,1.0.0
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerviper.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerviper.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerviper.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerviper.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -8,6 +8,7 @@ files = rw,device_idle_time,600
         r,device_serial,XX0000000078
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,logo_led_brightness,0
         w,logo_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razervipermini.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razervipermini.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razervipermini.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razervipermini.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -8,6 +8,7 @@ files = rw,device_idle_time,600
         r,device_serial,XX000000008A
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,logo_led_brightness,0
         w,logo_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerviperultimatewired.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerviperultimatewired.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerviperultimatewired.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerviperultimatewired.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -11,6 +11,7 @@ files = r,charge_level,255
         r,device_serial,XX000000007A
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,logo_led_brightness,0
         w,logo_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerviperultimatewireless.cfg 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerviperultimatewireless.cfg
--- 3.4.0+dfsg-1/pylib/openrazer/_fake_driver/razerviperultimatewireless.cfg	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/openrazer/_fake_driver/razerviperultimatewireless.cfg	2022-12-04 11:49:31.000000000 +0000
@@ -13,6 +13,7 @@ files = w,charge_colour
         r,device_serial,XX000000007B
         r,device_type,%(name)s
         rw,dpi,800:800
+        rw,dpi_stages,0x010320032005dc05dc
         r,firmware_version,v1.0
         rw,logo_led_brightness,0
         w,logo_matrix_effect_breath
diff -pruN 3.4.0+dfsg-1/pylib/setup.py 3.5.1+dfsg-2/pylib/setup.py
--- 3.4.0+dfsg-1/pylib/setup.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/pylib/setup.py	2022-12-04 11:49:31.000000000 +0000
@@ -5,6 +5,20 @@ from setuptools import setup, find_packa
 
 setup(
     name="openrazer",
-    version="3.4.0",
-    packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"])
+    version="3.5.1",
+    packages=find_packages(exclude=["tests", "openrazer._fake_driver"]),
+    install_requires=['dbus-python', 'numpy'],
+    author="OpenRazer contributors",
+    description="Library for interacting with the OpenRazer daemon.",
+    license="GPLv2+",
+    url="https://openrazer.github.io/",
+    project_urls={
+        "Bug Tracker": "https://github.com/openrazer/openrazer/issues",
+        "Source Code": "https://github.com/openrazer/openrazer/tree/master/pylib",
+    },
+    classifiers=[
+        "Programming Language :: Python :: 3",
+        "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
+        "Operating System :: POSIX :: Linux",
+    ],
 )
diff -pruN 3.4.0+dfsg-1/README.md 3.5.1+dfsg-2/README.md
--- 3.4.0+dfsg-1/README.md	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/README.md	2022-12-04 11:49:31.000000000 +0000
@@ -71,7 +71,7 @@ The devices below are fully feature supp
 | Razer Blade 15 Base (Early 2020)              |  1532:0255  |
 | Razer Blade Pro 17 (Early 2020)               |  1532:0256  |
 | Razer Huntsman Mini                           |  1532:0257  |
-| Razer BlackWidow V3 Mini Hyperspeed           |  1532:0258  |
+| Razer BlackWidow V3 Mini Hyperspeed (Wired)   |  1532:0258  |
 | Razer Blade Stealth (Late 2020)               |  1532:0259  |
 | Razer BlackWidow V3 Pro (Wired)               |  1532:025A  |
 | Razer Ornata V2                               |  1532:025D  |
@@ -79,8 +79,10 @@ The devices below are fully feature supp
 | Razer Huntsman V2 Analog                      |  1532:0266  |
 | Razer Huntsman Mini (JP)                      |  1532:0269  |
 | Razer Book 13 (2020)                          |  1532:026A  |
+| Razer Huntsman V2 TKL                         |  1532:026B  |
 | Razer Huntsman V2                             |  1532:026C  |
 | Razer Blade 15 Advanced (Early 2021)          |  1532:026D  |
+| Razer Blade 17 Pro (Early 2021)               |  1532:026E  |
 | Razer Blade 15 Base (Early 2021)              |  1532:026F  |
 | Razer Blade 14 (2021)                         |  1532:0270  |
 | Razer BlackWidow V3 Mini Hyperspeed (Wireless)|  1532:0271  |
@@ -89,6 +91,7 @@ The devices below are fully feature supp
 | Razer Huntsman Mini Analog                    |  1532:0282  |
 | Razer Blade 15 Advanced (Early 2022)          |  1532:028A  |
 | Razer Blade 17 (2022)                         |  1532:028B  |
+| Razer DeathStalker V2                         |  1532:0295  |
 | Razer BlackWidow V3 Tenkeyless                |  1532:0A24  |
 
 ### Mice
@@ -162,11 +165,14 @@ The devices below are fully feature supp
 | Razer Viper 8KHz                              |  1532:0091  |
 | Razer Orochi V2 (Receiver)                    |  1532:0094  |
 | Razer Orochi V2 (Bluetooth)                   |  1532:0095  |
+| Razer Naga X                                  |  1532:0096  |
 | Razer DeathAdder Essential (2021)             |  1532:0098  |
 | Razer Basilisk V3                             |  1532:0099  |
 | Razer DeathAdder V2 X HyperSpeed              |  1532:009C  |
 | Razer Viper V2 Pro (Wired)                    |  1532:00A5  |
 | Razer Viper V2 Pro (Wireless)                 |  1532:00A6  |
+| Razer DeathAdder V3 Pro (Wired)               |  1532:00B6  |
+| Razer DeathAdder V3 Pro (Wireless)            |  1532:00B7  |
 
 ### Mousemats
 | Device                                        | USB VID:PID |
diff -pruN 3.4.0+dfsg-1/scripts/ci/test-daemon.py 3.5.1+dfsg-2/scripts/ci/test-daemon.py
--- 3.4.0+dfsg-1/scripts/ci/test-daemon.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/scripts/ci/test-daemon.py	2022-12-04 11:49:31.000000000 +0000
@@ -2,13 +2,43 @@
 import openrazer.client
 
 devmgr = openrazer.client.DeviceManager()
+passed = True
 
-for d in devmgr.devices:
-    # Sanity check matrix capabilities
+
+def _test_failed(name, msg):
+    global passed
+    passed = False
+    print(f"\nFAILED: {name}\n       ", msg)
+
+
+def test_sanity_check_matrix_capabilities(d):
     if d.has("lighting_led_matrix"):
         d.fx.advanced.matrix[0, 0] = [0, 255, 0]
         try:
             d.fx.advanced.draw()
         except Exception as e:
-            print('\n~~~ ' + d.name + ' ~~~\n')
-            print(e)
+            _test_failed(d.name, e)
+
+
+def test_wired_wireless_naming():
+    # Enforce the (Wired) or (Wireless) suffix naming convention when devices have multiple PIDs
+    device_names = list(map(lambda device: device.name, devmgr.devices))
+
+    for name in device_names:
+        if name.find("(Wired)") != -1:
+            striped_name = name.replace("(Wired)", "").strip()
+            if striped_name in device_names:
+                _test_failed(striped_name, "Naming pattern is inconsistent. Append \"(Wireless)\" for the other USB PID.")
+
+        elif name.find("(Wireless)") != -1:
+            striped_name = name.replace("(Wireless)", "").strip()
+            if striped_name in device_names:
+                _test_failed(striped_name, "Naming pattern is inconsistent. Append \"(Wired)\" for the other USB PID.")
+
+
+for d in devmgr.devices:
+    test_sanity_check_matrix_capabilities(d)
+test_wired_wireless_naming()
+
+if not passed:
+    exit(1)
diff -pruN 3.4.0+dfsg-1/scripts/generate_fake_driver.sh 3.5.1+dfsg-2/scripts/generate_fake_driver.sh
--- 3.4.0+dfsg-1/scripts/generate_fake_driver.sh	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/scripts/generate_fake_driver.sh	2022-12-04 11:49:31.000000000 +0000
@@ -103,6 +103,19 @@ declare -A files_metadata=(
     ["tilt_hwheel"]="rw;0"
     ["tilt_repeat"]="rw;0"
     ["tilt_repeat_delay"]="rw;0"
+    ["reset_channels"]="w;1"
+    ["channel1_size"]="rw;8"
+    ["channel2_size"]="rw;8"
+    ["channel3_size"]="rw;8"
+    ["channel4_size"]="rw;8"
+    ["channel5_size"]="rw;8"
+    ["channel6_size"]="rw;8"
+    ["channel1_led_brightness"]="rw;0"
+    ["channel2_led_brightness"]="rw;0"
+    ["channel3_led_brightness"]="rw;0"
+    ["channel4_led_brightness"]="rw;0"
+    ["channel5_led_brightness"]="rw;0"
+    ["channel6_led_brightness"]="rw;0"
     ["version"]="r;1.0.0"
 )
 
@@ -119,7 +132,7 @@ byte_dpi_devices=(
 
 
 get_attr_from_create_device_file() {
-    sed -n 's/[[:space:]]\+CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_\([[:lower:]_]\+\));.*/\1/p'
+    sed -n 's/[[:space:]]\+CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_\([[:lower:][:digit:]_]\+\));.*/\1/p'
 }
 
 driver=$1
diff -pruN 3.4.0+dfsg-1/scripts/razer_mouse/driver/set_mouse_dpi.py 3.5.1+dfsg-2/scripts/razer_mouse/driver/set_mouse_dpi.py
--- 3.4.0+dfsg-1/scripts/razer_mouse/driver/set_mouse_dpi.py	2022-07-31 16:01:10.000000000 +0000
+++ 3.5.1+dfsg-2/scripts/razer_mouse/driver/set_mouse_dpi.py	2022-12-04 11:49:31.000000000 +0000
@@ -22,8 +22,8 @@ def parse_args():
     parser = argparse.ArgumentParser(description="Set the mouse DPI")
     parser.add_argument('-d', '--device', type=str, help="Device string like \"0003:1532:0045.000C\"")
 
-    parser.add_argument('--dpi_x', required=True, type=int, help="DPI on the X axis (100, 26000)")
-    parser.add_argument('--dpi_y', type=int, help="DPI on the Y axis (if omitted, dpi_x is used), (100, 26000)")
+    parser.add_argument('--dpi_x', required=True, type=int, help="DPI on the X axis (100, 30000)")
+    parser.add_argument('--dpi_y', type=int, help="DPI on the Y axis (if omitted, dpi_x is used), (100, 30000)")
 
     args = parser.parse_args()
     return args
@@ -50,11 +50,11 @@ def run():
         print("Multiple mouse directories found. Rerun with -d", file=sys.stderr)
         sys.exit(1)
 
-    dpi_x = clamp_to_min_max(args.dpi_x, 100, 26000)
+    dpi_x = clamp_to_min_max(args.dpi_x, 100, 30000)
     if args.dpi_y is None:
         byte_string = struct.pack(">H", dpi_x)
     else:
-        dpi_y = clamp_to_min_max(args.dpi_y, 100, 26000)
+        dpi_y = clamp_to_min_max(args.dpi_y, 100, 30000)
         byte_string = struct.pack(">HH", dpi_x, dpi_y)
 
     set_mouse_dpi_filepath = os.path.join(mouse_dir, "dpi")
