driver: added basic razer driver (viper mini)
This commit is contained in:
		
							
								
								
									
										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