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