forked from drath/libratbag
242 lines
7.0 KiB
C
242 lines
7.0 KiB
C
#pragma once
|
|
|
|
#include <linux/input.h>
|
|
#include <stdint.h>
|
|
|
|
#include "libratbag-private.h"
|
|
#include "libratbag-hidraw.h"
|
|
|
|
#define ASUS_QUIRK_DOUBLE_DPI 1 << 0
|
|
#define ASUS_QUIRK_STRIX_PROFILE 1 << 1
|
|
#define ASUS_QUIRK_BATTERY_V2 1 << 2
|
|
|
|
#define ASUS_PACKET_SIZE 64
|
|
#define ASUS_BUTTON_ACTION_TYPE_KEY 0 /* keyboard key */
|
|
#define ASUS_BUTTON_ACTION_TYPE_BUTTON 1 /* mouse button */
|
|
#define ASUS_BUTTON_CODE_DISABLED 0xff /* disabled mouse button */
|
|
#define ASUS_STATUS_ERROR 0xaaff /* invalid state/request, disconnected or sleeping */
|
|
|
|
/* maximum number of buttons across all ASUS devices */
|
|
#define ASUS_MAX_NUM_BUTTON 17
|
|
|
|
/* maximum number of DPI presets across all ASUS devices */
|
|
/* for 4 DPI devices: 0 - red, 1 - purple, 2 - blue (default), 3 - green */
|
|
/* for 2 DPI devices: 0 - main (default), 1 - alternative */
|
|
#define ASUS_MAX_NUM_DPI 4
|
|
|
|
/* maximum number of LEDs across all ASUS devices */
|
|
#define ASUS_MAX_NUM_LED 3
|
|
|
|
/* base request */
|
|
|
|
struct _asus_request {
|
|
uint16_t cmd;
|
|
uint8_t params[ASUS_PACKET_SIZE - 2];
|
|
} __attribute__((packed));
|
|
_Static_assert(sizeof(struct _asus_request) == ASUS_PACKET_SIZE, "The size of `_asus_request` is wrong.");
|
|
|
|
union asus_request {
|
|
struct _asus_request data;
|
|
uint8_t raw[ASUS_PACKET_SIZE];
|
|
};
|
|
|
|
/* base response */
|
|
|
|
struct _asus_response {
|
|
uint16_t code;
|
|
uint8_t results[ASUS_PACKET_SIZE - 2];
|
|
} __attribute__((packed));
|
|
_Static_assert(sizeof(struct _asus_response) == ASUS_PACKET_SIZE, "The size of `_asus_response` is wrong.");
|
|
|
|
union asus_response {
|
|
struct _asus_response data;
|
|
uint8_t raw[ASUS_PACKET_SIZE];
|
|
};
|
|
|
|
/* current profile ID and firmware info */
|
|
|
|
struct asus_profile_data {
|
|
unsigned int profile_id;
|
|
uint8_t version_primary_major;
|
|
uint8_t version_primary_minor;
|
|
uint8_t version_primary_build;
|
|
uint8_t version_secondary_major;
|
|
uint8_t version_secondary_minor;
|
|
uint8_t version_secondary_build;
|
|
} __attribute__((packed));
|
|
|
|
/* button bindings */
|
|
|
|
struct _asus_binding {
|
|
uint8_t action; /* ASUS code (for both keyboard keys and mouse buttons) */
|
|
uint8_t type; /* ASUS action type */
|
|
} __attribute__((packed));
|
|
|
|
struct _asus_binding_data {
|
|
uint32_t pad;
|
|
struct _asus_binding binding[ASUS_MAX_NUM_BUTTON];
|
|
} __attribute__((packed));
|
|
|
|
union asus_binding_data {
|
|
struct _asus_binding_data data;
|
|
uint8_t raw[ASUS_PACKET_SIZE];
|
|
};
|
|
|
|
/* DPI data */
|
|
|
|
struct _asus_dpi2_data {
|
|
uint32_t pad;
|
|
uint16_t dpi[2]; /* DPI presets */
|
|
uint16_t rate; /* polling rate */
|
|
uint16_t response; /* button response */
|
|
uint16_t snapping; /* angle snapping (on/off) */
|
|
} __attribute__((packed)); /* struct for storing 2 DPI presets and extra settings */
|
|
|
|
struct _asus_dpi4_data {
|
|
uint32_t pad;
|
|
uint16_t dpi[4];
|
|
uint16_t rate;
|
|
uint16_t response;
|
|
uint16_t snapping;
|
|
} __attribute__((packed)); /* struct for storing 4 DPI presets and extra settings */
|
|
|
|
union asus_resolution_data {
|
|
struct _asus_dpi2_data data2; /* data for 2 DPI presets */
|
|
struct _asus_dpi4_data data4; /* data for 4 DPI presets */
|
|
uint8_t raw[sizeof(struct _asus_dpi4_data)];
|
|
};
|
|
|
|
/* LED data */
|
|
|
|
struct _asus_led {
|
|
uint8_t mode;
|
|
uint8_t brightness; /* 0-4 */
|
|
uint8_t r;
|
|
uint8_t g;
|
|
uint8_t b;
|
|
} __attribute__((packed));
|
|
|
|
struct _asus_led_data {
|
|
uint32_t pad;
|
|
struct _asus_led led[ASUS_MAX_NUM_LED]; /* LEDs */
|
|
} __attribute__((packed));
|
|
|
|
union asus_led_data {
|
|
struct _asus_led_data data;
|
|
uint8_t raw[sizeof(struct _asus_led_data)];
|
|
};
|
|
|
|
/* button define */
|
|
struct asus_button {
|
|
uint8_t asus_code; /* used for button action */
|
|
enum ratbag_button_action_type type;
|
|
uint8_t button; /* mouse button number, optional */
|
|
enum ratbag_button_action_special special; /* special action, optional */
|
|
};
|
|
|
|
/* ASUS code, button type, button number, special button action */
|
|
static const struct asus_button ASUS_BUTTON_MAPPING[] = {
|
|
{ 0xf0, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 1, 0 }, /* left */
|
|
{ 0xf1, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 2, 0 }, /* right (button 3 in xev) */
|
|
{ 0xf2, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 3, 0 }, /* middle (button 2 in xev) */
|
|
{ 0xe8, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_UP },
|
|
{ 0xe9, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_DOWN },
|
|
{ 0xe6, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP },
|
|
{ 0xe4, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 4, 0 }, /* backward, left side */
|
|
{ 0xe5, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 5, 0 }, /* forward, left side */
|
|
{ 0xe1, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 4, 0 }, /* backward, right side */
|
|
{ 0xe2, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 5, 0 }, /* forward, right side */
|
|
{ 0xe7, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_ALTERNATE }, /* DPI target */
|
|
{ 0xea, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button A */
|
|
{ 0xeb, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button B */
|
|
{ 0xec, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button C */
|
|
{ 0xed, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button D */
|
|
{ 0xee, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button E */
|
|
{ 0xef, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button F */
|
|
};
|
|
|
|
const struct asus_button *
|
|
asus_find_button_by_action(struct ratbag_button_action action);
|
|
|
|
const struct asus_button *
|
|
asus_find_button_by_code(uint8_t asus_code);
|
|
|
|
int
|
|
asus_find_key_code(unsigned int linux_code);
|
|
|
|
/*
|
|
* @param asus_code ASUS key code.
|
|
* @return Linux key code (as defined defined in linux/input-event-codes.h) or
|
|
* -1 on error.
|
|
*/
|
|
int
|
|
asus_get_linux_key_code(uint8_t asus_code);
|
|
|
|
/* initializers of ratbag data */
|
|
|
|
void
|
|
asus_setup_profile(struct ratbag_device *device, struct ratbag_profile *profile);
|
|
|
|
void
|
|
asus_setup_button(struct ratbag_device *device, struct ratbag_button *button);
|
|
|
|
void
|
|
asus_setup_resolution(struct ratbag_device *device, struct ratbag_resolution *resolution);
|
|
|
|
void
|
|
asus_setup_led(struct ratbag_device *device, struct ratbag_led *led);
|
|
|
|
/* generic i/o */
|
|
|
|
int
|
|
asus_query(struct ratbag_device *device, union asus_request *request, union asus_response *response);
|
|
|
|
/* commit */
|
|
|
|
int
|
|
asus_save_profile(struct ratbag_device *device);
|
|
|
|
/* profiles */
|
|
|
|
int
|
|
asus_get_profile_data(struct ratbag_device *device, struct asus_profile_data *data);
|
|
|
|
int
|
|
asus_set_profile(struct ratbag_device *device, unsigned int index);
|
|
|
|
/* button bindings */
|
|
|
|
int
|
|
asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *data);
|
|
|
|
int
|
|
asus_set_button_action(struct ratbag_device *device, uint8_t asus_code_src,
|
|
uint8_t asus_code_dst, uint8_t asus_type);
|
|
|
|
/* resolution settings */
|
|
|
|
int
|
|
asus_get_resolution_data(struct ratbag_device *device, union asus_resolution_data *data);
|
|
|
|
int
|
|
asus_set_dpi(struct ratbag_device *device, unsigned int index, unsigned int dpi);
|
|
|
|
int
|
|
asus_set_polling_rate(struct ratbag_device *device, unsigned int hz);
|
|
|
|
int
|
|
asus_set_button_response(struct ratbag_device *device, unsigned int ms);
|
|
|
|
int
|
|
asus_set_angle_snapping(struct ratbag_device *device, bool is_enabled);
|
|
|
|
/* LED settings */
|
|
|
|
int
|
|
asus_get_led_data(struct ratbag_device *device, union asus_led_data *data);
|
|
|
|
int
|
|
asus_set_led(struct ratbag_device *device,
|
|
uint8_t index, uint8_t mode, uint8_t brightness,
|
|
struct ratbag_color color);
|