Compare commits
	
		
			2 Commits
		
	
	
		
			894b7a98b8
			...
			356d0b975d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 356d0b975d | |||
| 34e4828ee7 | 
| @@ -2,7 +2,6 @@ CC=gcc | ||||
| CFLAGS=$(shell pkg-config --cflags libusb-1.0) -O3 -Wall -shared | ||||
| LDFLAGS=$(shell pkg-config --libs libusb-1.0) | ||||
|  | ||||
| ASSETS=$(shell find devices/ -name '*.png') | ||||
| FINAL_ASSETS=$(BUILD_DIR)/drivers/assets/gwolves-htx.png $(BUILD_DIR)/drivers/assets/gwolves-hts_plus.png $(BUILD_DIR)/drivers/assets/gwolves-hsk_pro.png | ||||
| BUILD_DIR=../../build/ | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| #ifndef G_WOLVES_H | ||||
| #define G_WOLVES_H | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include <stddef.h> | ||||
| @@ -195,3 +198,5 @@ struct REPORT_WIRELESS_FIRMWARE_VERSION | ||||
|     uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 7]; | ||||
| } __attribute__((packed)); | ||||
| static_assert(sizeof(struct REPORT_WIRELESS_FIRMWARE_VERSION) == REPORT_MAX_SIZE, "Report WIRELESS_FIRMWARE_VERSION not of right size"); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										13
									
								
								drivers/razer/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								drivers/razer/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| CC=gcc | ||||
| CFLAGS=$(shell pkg-config --cflags libusb-1.0) -O3 -Wall -shared | ||||
| LDFLAGS=$(shell pkg-config --libs libusb-1.0) | ||||
|  | ||||
| FINAL_ASSETS=$(BUILD_DIR)/drivers/assets/razer-viper_mini.png | ||||
| BUILD_DIR=../../build/ | ||||
|  | ||||
| all: $(BUILD_DIR)/drivers/razer.so $(FINAL_ASSETS) | ||||
|  | ||||
| $(BUILD_DIR)/drivers/razer.so: razer.c | $(BUILD_DIR)/drivers/ | ||||
| 	$(CC) $(CFLAGS) -o $@ $^ | ||||
| $(BUILD_DIR)/drivers/assets/%.png: %.png | $(BUILD_DIR)/drivers/assets | ||||
| 	cp $^ $@ | ||||
							
								
								
									
										
											BIN
										
									
								
								drivers/razer/razer-viper_mini.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								drivers/razer/razer-viper_mini.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 299 KiB | 
							
								
								
									
										106
									
								
								drivers/razer/razer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								drivers/razer/razer.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| #include "razer.h" | ||||
|  | ||||
| static uint8_t compute_crc(void* report) | ||||
| { | ||||
|     uint8_t* r = report; | ||||
|  | ||||
|     uint8_t crc = 0; | ||||
|     for(size_t i = 2; i < REPORT_SIZE - sizeof(report_footer_t); i++) | ||||
|     { | ||||
|         crc ^= r[i]; | ||||
|     } | ||||
|  | ||||
|     return crc; | ||||
| } | ||||
|  | ||||
| static int send_command(libusb_device_handle* hand, uint8_t command_class, uint8_t command, uint8_t size, void* report) | ||||
| { | ||||
|     report_header_t* head = report; | ||||
|     head->report_size = size; | ||||
|     head->command_class = command_class; | ||||
|     head->command_id = command; | ||||
|  | ||||
|     report_footer_t* footer = report + REPORT_SIZE - sizeof(report_footer_t); | ||||
|     footer->crc = compute_crc(report); | ||||
|  | ||||
|     // Send command | ||||
|     int res = libusb_control_transfer(hand, | ||||
|     0x21, // request type | ||||
|     0x09, // request (SET_REPORT) | ||||
|     0x300, // wValue (FEATURE << 8 | REPORT(0)) | ||||
|     0x0, // wIndex = 0x0 : interface | ||||
|     report, | ||||
|     REPORT_SIZE, // wLength = 90 | ||||
|     0 /* timeout*/); | ||||
|  | ||||
|     if(res <= 0) return res; | ||||
|  | ||||
|     // Wait for the mouse to catch the report | ||||
|     usleep(100); | ||||
|  | ||||
|     // Get response report | ||||
|     res = libusb_control_transfer(hand, | ||||
|     0xa1, // request type | ||||
|     0x01, // request (GET_REPORT) | ||||
|     0x300, // wValue (FEATURE << 8 | REPORT(0)) | ||||
|     0x0, // wIndex = 0x0 : interface | ||||
|     report, | ||||
|     REPORT_SIZE, // wLength = 90 | ||||
|     0); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| void driver_init(void) {} | ||||
|  | ||||
| uint32_t driver_getkey(void) | ||||
| { | ||||
|     static int count = 0; | ||||
|     count++; | ||||
|  | ||||
|     // Register ALL razer compatible devices | ||||
|     uint16_t id = 0; | ||||
|     switch(count) | ||||
|     { | ||||
|         case 1: | ||||
|             id = VIPER_MINI_PRODUCT_ID; | ||||
|             break; | ||||
|         default: | ||||
|             id = 0; | ||||
|     } | ||||
|      | ||||
|     if(id == 0) return 0; | ||||
|     return (VENDOR_ID << 16) | id; | ||||
| } | ||||
|  | ||||
| char* driver_get_name(void* handle) | ||||
| { | ||||
|     libusb_device* dev = handle; | ||||
|  | ||||
|     struct libusb_device_descriptor desc; | ||||
|     libusb_get_device_descriptor(dev, &desc); | ||||
|  | ||||
|     switch(desc.idProduct) | ||||
|     { | ||||
|         case VIPER_MINI_PRODUCT_ID: | ||||
|             return VIPER_MINI_NAME; | ||||
|         default: | ||||
|             return "Unknown Razer mice"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| char* driver_get_image(void* handle) | ||||
| { | ||||
|     libusb_device* dev = handle; | ||||
|  | ||||
|     struct libusb_device_descriptor desc; | ||||
|     libusb_get_device_descriptor(dev, &desc); | ||||
|  | ||||
|     switch(desc.idProduct) | ||||
|     { | ||||
|         case VIPER_MINI_PRODUCT_ID: | ||||
|             return VIPER_MINI_IMAGE; | ||||
|         default: | ||||
|             return ""; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										148
									
								
								drivers/razer/razer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								drivers/razer/razer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| #ifndef RAZER_H | ||||
| #define RAZER_H | ||||
|  | ||||
| #include <libusb.h> | ||||
| #include <stdlib.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| #define VENDOR_ID 0x1532 | ||||
|  | ||||
| #define REPORT_SIZE 90 | ||||
|  | ||||
| /* Devices */ | ||||
| #include "viper_mini.h" | ||||
|  | ||||
| typedef struct REPORT_HEADER | ||||
| { | ||||
|     uint8_t status; | ||||
|     uint8_t transaction_id; | ||||
|      | ||||
|     uint8_t remaining_packets_high; | ||||
|     uint8_t remaining_packets_low; | ||||
|     uint8_t protocol_type; // 0x0 | ||||
|     uint8_t report_size; | ||||
|  | ||||
|     uint8_t command_class; | ||||
|     uint8_t command_id; | ||||
| } __attribute__((packed)) report_header_t; | ||||
|  | ||||
| typedef struct REPORT_FOOTER | ||||
| { | ||||
|     uint8_t crc; // Control, xored bytes of report | ||||
|     uint8_t reserved; | ||||
| } __attribute__((packed)) report_footer_t; | ||||
|  | ||||
| /* Commands of the BASIC (0x0) class */ | ||||
| #define COMMAND_CLASS_BASIC 0x0 | ||||
|  | ||||
| struct REPORT_FIRMWARE_VERSION | ||||
| { | ||||
|     report_header_t header; | ||||
|  | ||||
|     uint8_t version_major; | ||||
|     uint8_t version_minor; | ||||
|  | ||||
|     uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 2]; | ||||
|  | ||||
|     report_footer_t footer; | ||||
| } __attribute__((packed)); | ||||
| #define REPORT_SIZE_FIRMWARE_VERSION 0x2 | ||||
| #define COMMAND_REPORT_FIRMWARE_VERSION 0x81 | ||||
| static_assert(sizeof(struct REPORT_FIRMWARE_VERSION) == REPORT_SIZE, "REPORT_FIRMWARE_VERSION is not of the right size"); | ||||
|  | ||||
| struct REPORT_POLLING_RATE | ||||
| { | ||||
|     report_header_t header; | ||||
|  | ||||
|     // There is another report for up to 8000Hz polling | ||||
|     // 0x01: 1000Hz, 0x2: 500Hz, 0x3: 125Hz | ||||
|     uint8_t polling_rate; | ||||
|  | ||||
|     uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 1]; | ||||
|  | ||||
|     report_footer_t footer; | ||||
| } __attribute__((packed)); | ||||
| static_assert(sizeof(struct REPORT_POLLING_RATE) == REPORT_SIZE, "REPORT_POLLING_RATE is not of the right size"); | ||||
| #define REPORT_SIZE_POLLING_RATE 0x1 | ||||
| #define COMMAND_REPORT_POLLING_RATE 0x85 | ||||
|  | ||||
| /* Commands of the DPI (0x4) class */ | ||||
| #define COMMAND_CLASS_DPI 0x4 | ||||
|  | ||||
| struct REPORT_DPI | ||||
| { | ||||
|     report_header_t header; | ||||
|  | ||||
|     uint8_t variable_storage; | ||||
|     uint8_t dpi_x_high; | ||||
|     uint8_t dpi_x_low; | ||||
|     uint8_t dpi_y_high; | ||||
|     uint8_t dpi_y_low; | ||||
|     uint8_t unknown_0; | ||||
|     uint8_t unknown_1; | ||||
|  | ||||
|     uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 7]; | ||||
|  | ||||
|     report_footer_t footer; | ||||
| } __attribute__((packed)); | ||||
| static_assert(sizeof(struct REPORT_DPI) == REPORT_SIZE, "REPORT_DPI is not of the right size"); | ||||
| #define REPORT_SIZE_DPI 0x07 | ||||
| #define COMMAND_REPORT_DPI 0x85 | ||||
|  | ||||
| typedef struct DPI_STAGE | ||||
| { | ||||
|     uint8_t stage_index; | ||||
|     uint8_t dpi_x_high; | ||||
|     uint8_t dpi_x_low; | ||||
|     uint8_t dpi_y_high; | ||||
|     uint8_t dpi_y_low; | ||||
|     uint8_t unknown_0; | ||||
|     uint8_t unknown_1; | ||||
| } __attribute__((packed)) dpi_stage_t; | ||||
| struct REPORT_DPI_STAGES | ||||
| { | ||||
|     report_header_t header; | ||||
|  | ||||
|     uint8_t variable_storage; | ||||
|     uint8_t active_dpi_stage; | ||||
|     uint8_t dpi_stages_count; | ||||
|  | ||||
|     dpi_stage_t stages[5]; | ||||
|  | ||||
|     uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 38]; | ||||
|  | ||||
|     report_footer_t footer; | ||||
| } __attribute__((packed)); | ||||
| static_assert(sizeof(struct REPORT_DPI_STAGES) == REPORT_SIZE, "REPORT_DPI_STAGES is not of the right size"); | ||||
| #define REPORT_SIZE_DPI_STAGES 0x26 | ||||
| #define COMMAND_REPORT_DPI_STAGES 0x86 | ||||
|  | ||||
| /* Commands of the BATTERY (0x7) class */ | ||||
| #define COMMAND_CLASS_BATTERY 0x7 | ||||
|  | ||||
| struct REPORT_BATTERY_LEVEL | ||||
| { | ||||
|     report_header_t header; | ||||
|  | ||||
|     uint8_t ignored; | ||||
|     uint8_t battery_level; // 0-255 | ||||
|  | ||||
|     report_footer_t footer; | ||||
| } __attribute__((packed)); | ||||
| #define REPORT_SIZE_BATTERY_LEVEL 0x2 | ||||
| #define COMMAND_REPORT_BATTERY_LEVEL 0x80 | ||||
|  | ||||
| struct REPORT_BATTERY_STATUS | ||||
| { | ||||
|     report_header_t header; | ||||
|  | ||||
|     uint8_t ignored; | ||||
|     uint8_t charging; // 0: not charging, 1:charging | ||||
|  | ||||
|     report_footer_t footer; | ||||
| } __attribute__((packed)); | ||||
| #define REPORT_SIZE_BATTERY_STATUS 0x2 | ||||
| #define COMMAND_REPORT_BATTERY_STATUS 0x84 | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										8
									
								
								drivers/razer/viper_mini.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								drivers/razer/viper_mini.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| #ifndef VIPER_MINI_H | ||||
| #define VIPER_MINI_H | ||||
|  | ||||
| #define VIPER_MINI_PRODUCT_ID 0x008a | ||||
| #define VIPER_MINI_NAME "Viper Mini" | ||||
| #define VIPER_MINI_IMAGE "razer-viper_mini.png" | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user