From a095508ce16460bfcd3f6e462e2ffd47d2f7bae6 Mon Sep 17 00:00:00 2001
From: Mathilde Gilles <ma.gilles@criteo.com>
Date: Thu, 10 Dec 2020 01:11:18 +0100
Subject: [PATCH] Add support for Razer Ornata Chroma V2

---
 README.md                                     |  1 +
 daemon/openrazer_daemon/hardware/keyboards.py | 21 +++++++++++++++++++
 driver/razerkbd_driver.c                      | 21 +++++++++++++++++++
 driver/razerkbd_driver.h                      |  1 +
 ...io.github.openrazer.openrazer.metainfo.xml |  1 +
 install_files/udev/99-razer.rules             |  2 +-
 .../_fake_driver/razerornatachromav2.cfg      | 21 +++++++++++++++++++
 7 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 pylib/openrazer/_fake_driver/razerornatachromav2.cfg

diff --git a/README.md b/README.md
index 86111dc9..23f47ee3 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,7 @@ The devices below are fully feature supported by OpenRazer, which means all avai
 | Razer Blade 15 Advanced (2020)                |  1532:0253  |
 | Razer Blade 15 (Early 2020) Base              |  1532:0255  |
 | Razer Blade Stealth (Late 2020)               |  1532:0259  |
+| Razer Ornata Chroma V2                        |  1532:025D  |
 | Razer Cynosa V2                               |  1532:025E  |
 
 ### Mice
diff --git a/daemon/openrazer_daemon/hardware/keyboards.py b/daemon/openrazer_daemon/hardware/keyboards.py
index c9a88ea5..90528ed8 100644
--- a/daemon/openrazer_daemon/hardware/keyboards.py
+++ b/daemon/openrazer_daemon/hardware/keyboards.py
@@ -607,6 +607,27 @@ class RazerOrnataChroma(_RippleKeyboard):
     DEVICE_IMAGE = "https://assets.razerzone.com/eeimages/support/products/727/727_ornata_chroma.png"
 
 
+class RazerOrnataChromaV2(_RippleKeyboard):
+    """
+    Class for the Razer Ornata Chroma
+    """
+    EVENT_FILE_REGEX = re.compile(r'.*Ornata_Chroma_V2(-if01)?-event-kbd')
+
+    USB_VID = 0x1532
+    USB_PID = 0x025D
+    HAS_MATRIX = True
+    WAVE_DIRS = (1, 2)
+    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://assets.razerzone.com/eeimages/support/products/727/727_ornata_chroma.png"
+
+
 class RazerHuntsmanElite(_RippleKeyboard):
     """
     Class for the Razer Huntsman Elite
diff --git a/driver/razerkbd_driver.c b/driver/razerkbd_driver.c
index dd24ea00..bb7d0526 100644
--- a/driver/razerkbd_driver.c
+++ b/driver/razerkbd_driver.c
@@ -151,6 +151,7 @@ static int razer_get_report(struct usb_device *usb_dev, struct razer_report *req
     switch (usb_dev->descriptor.idProduct) {
     case USB_DEVICE_ID_RAZER_ANANSI:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_TE:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         report_index = 0x02;
         response_index = 0x02;
         break;
@@ -226,6 +227,7 @@ static void razer_set_device_mode(struct usb_device *usb_dev, unsigned char mode
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_LITE:
     case USB_DEVICE_ID_RAZER_ORNATA:
     case USB_DEVICE_ID_RAZER_ORNATA_CHROMA:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
     case USB_DEVICE_ID_RAZER_CYNOSA_CHROMA:
     case USB_DEVICE_ID_RAZER_CYNOSA_LITE:
         report.transaction_id.id = 0x3F;
@@ -525,6 +527,10 @@ static ssize_t razer_attr_read_device_type(struct device *dev, struct device_att
         device_type = "Razer Ornata Chroma\n";
         break;
 
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
+        device_type = "Razer Ornata Chroma V2\n";
+        break;
+
     case USB_DEVICE_ID_RAZER_HUNTSMAN_ELITE:
         device_type = "Razer Huntsman Elite\n";
         break;
@@ -584,6 +590,7 @@ static ssize_t razer_attr_write_mode_macro_effect(struct device *dev, struct dev
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_LITE:
     case USB_DEVICE_ID_RAZER_ORNATA:
     case USB_DEVICE_ID_RAZER_ORNATA_CHROMA:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_ELITE:
     case USB_DEVICE_ID_RAZER_HUNTSMAN_TE:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_2019:
@@ -895,6 +902,7 @@ static ssize_t razer_attr_write_mode_none(struct device *dev, struct device_attr
     case USB_DEVICE_ID_RAZER_TARTARUS_V2:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         report = razer_chroma_extended_matrix_effect_none(VARSTORE, BACKLIGHT_LED);
         report.transaction_id.id = 0x1F;
         break;
@@ -953,6 +961,7 @@ static ssize_t razer_attr_write_mode_wave(struct device *dev, struct device_attr
     case USB_DEVICE_ID_RAZER_TARTARUS_V2:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         report = razer_chroma_extended_matrix_effect_wave(VARSTORE, BACKLIGHT_LED, direction);
         report.transaction_id.id = 0x1F;
         break;
@@ -991,6 +1000,7 @@ static ssize_t razer_attr_write_mode_spectrum(struct device *dev, struct device_
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         report = razer_chroma_extended_matrix_effect_spectrum(VARSTORE, BACKLIGHT_LED);
         report.transaction_id.id = 0x1F;
         break;
@@ -1048,6 +1058,7 @@ static ssize_t razer_attr_write_mode_reactive(struct device *dev, struct device_
         case USB_DEVICE_ID_RAZER_TARTARUS_V2:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
         case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+        case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
             report = razer_chroma_extended_matrix_effect_reactive(VARSTORE, BACKLIGHT_LED, speed, (struct razer_rgb*)&buf[1]);
             report.transaction_id.id = 0x1F;
             break;
@@ -1174,6 +1185,7 @@ static ssize_t razer_attr_write_mode_static(struct device *dev, struct device_at
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         if(count == 3) {
             report = razer_chroma_extended_matrix_effect_static(VARSTORE, BACKLIGHT_LED, (struct razer_rgb*)&buf[0]);
             report.transaction_id.id = 0x1F;
@@ -1254,6 +1266,7 @@ static ssize_t razer_attr_write_mode_starlight(struct device *dev, struct device
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_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]);
         } else if(count == 4) {
@@ -1411,6 +1424,7 @@ static ssize_t razer_attr_write_mode_breath(struct device *dev, struct device_at
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         if (count == 3) { // Single colour mode
             report = razer_chroma_extended_matrix_effect_breathing_single(VARSTORE, BACKLIGHT_LED, (struct razer_rgb*)&buf[0]);
         } else if (count == 6) { // Dual colour mode
@@ -1568,6 +1582,7 @@ static ssize_t razer_attr_write_mode_custom(struct device *dev, struct device_at
     case USB_DEVICE_ID_RAZER_TARTARUS_V2:
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         report = razer_chroma_extended_matrix_effect_custom_frame();
         report.transaction_id.id = 0x1F;
         break;
@@ -1662,6 +1677,7 @@ static ssize_t razer_attr_write_set_brightness(struct device *dev, struct device
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         report = razer_chroma_extended_matrix_brightness(VARSTORE, BACKLIGHT_LED, brightness);
         report.transaction_id.id = 0x1F;
         break;
@@ -1722,6 +1738,7 @@ static ssize_t razer_attr_read_set_brightness(struct device *dev, struct device_
 
     case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
     case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+    case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         report = razer_chroma_extended_matrix_get_brightness(VARSTORE, BACKLIGHT_LED);
         report.transaction_id.id = 0x1F;
         break;
@@ -1853,6 +1870,7 @@ static ssize_t razer_attr_write_matrix_custom_frame(struct device *dev, struct d
         case USB_DEVICE_ID_RAZER_TARTARUS_V2:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
         case USB_DEVICE_ID_RAZER_CYNOSA_V2:
+        case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
             report = razer_chroma_extended_matrix_set_custom_frame(row_id, start_col, stop_col, (unsigned char*)&buf[offset]);
             report.transaction_id.id = 0x1F;
             break;
@@ -2370,6 +2388,7 @@ static int razer_kbd_probe(struct hid_device *hdev, const struct hid_device_id *
             break;
 
         case USB_DEVICE_ID_RAZER_ORNATA_CHROMA:
+        case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_ELITE:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_TE:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_2019:
@@ -2707,6 +2726,7 @@ static void razer_kbd_disconnect(struct hid_device *hdev)
             break;
 
         case USB_DEVICE_ID_RAZER_ORNATA_CHROMA:
+        case USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_ELITE:
         case USB_DEVICE_ID_RAZER_HUNTSMAN_TE:
         case USB_DEVICE_ID_RAZER_BLACKWIDOW_2019:
@@ -2872,6 +2892,7 @@ static const struct hid_device_id razer_devices[] = {
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_X_CHROMA) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_X_CHROMA_TE) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_ORNATA_CHROMA) },
+    { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_CYNOSA_CHROMA) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_CYNOSA_LITE) },
     { HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_CYNOSA_V2) },
diff --git a/driver/razerkbd_driver.h b/driver/razerkbd_driver.h
index 335abdb9..88b9145a 100644
--- a/driver/razerkbd_driver.h
+++ b/driver/razerkbd_driver.h
@@ -70,6 +70,7 @@
 #define USB_DEVICE_ID_RAZER_BLADE_15_ADV_2020 0x0253
 #define USB_DEVICE_ID_RAZER_BLADE_EARLY_2020_BASE 0x0255
 #define USB_DEVICE_ID_RAZER_BLADE_STEALTH_LATE_2020 0x0259
+#define USB_DEVICE_ID_RAZER_ORNATA_CHROMA_V2 0x025D
 #define USB_DEVICE_ID_RAZER_CYNOSA_V2 0x025E
 
 /* Each keyboard report has 90 bytes*/
diff --git a/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml b/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml
index c1468889..871d52b6 100644
--- a/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml
+++ b/install_files/appstream/io.github.openrazer.openrazer.metainfo.xml
@@ -125,6 +125,7 @@
     <modalias>usb:v1532p0253d*</modalias>
     <modalias>usb:v1532p0255d*</modalias>
     <modalias>usb:v1532p0259d*</modalias>
+    <modalias>usb:v1532p025Dd*</modalias>
     <modalias>usb:v1532p025Ed*</modalias>
     <modalias>usb:v1532p0501d*</modalias>
     <modalias>usb:v1532p0504d*</modalias>
diff --git a/install_files/udev/99-razer.rules b/install_files/udev/99-razer.rules
index 8d03a06e..d5b36bd3 100644
--- a/install_files/udev/99-razer.rules
+++ b/install_files/udev/99-razer.rules
@@ -10,7 +10,7 @@ ATTRS{idProduct}=="0013|0016|0020|0024|0025|002e|002f|0032|0034|0036|0037|0038|0
     ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razermouse"
 
 # Keyboards
-ATTRS{idProduct}=="010d|010e|010f|0111|0113|011a|011b|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|022d|022f|0232|0233|0234|0235|0237|0239|023a|023b|023f|0240|0241|0243|0245|0246|024a|024c|024d|0252|0253|0255|0259|025e", \
+ATTRS{idProduct}=="010d|010e|010f|0111|0113|011a|011b|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|022d|022f|0232|0233|0234|0235|0237|0239|023a|023b|023f|0240|0241|0243|0245|0246|024a|024c|024d|0252|0253|0255|0259|025d|025e", \
     ATTRS{idVendor}=="1532", \
     ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razerkbd"
 
diff --git a/pylib/openrazer/_fake_driver/razerornatachromav2.cfg b/pylib/openrazer/_fake_driver/razerornatachromav2.cfg
new file mode 100644
index 00000000..b9bffda7
--- /dev/null
+++ b/pylib/openrazer/_fake_driver/razerornatachromav2.cfg
@@ -0,0 +1,21 @@
+[device]
+dir_name = 0003:1532:025D.0001
+name = Razer Ornata Chroma V2
+files = r,device_serial,XX000000025D
+        r,device_type,%(name)s
+        r,firmware_version,v1.0
+        rw,game_led_state,0
+        r,kbd_layout,01
+        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
-- 
GitLab