1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun #ifndef __HID_ROCCAT_KONE_H 3*4882a593Smuzhiyun #define __HID_ROCCAT_KONE_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun /* 6*4882a593Smuzhiyun * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun /* 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #include <linux/types.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun struct kone_keystroke { 15*4882a593Smuzhiyun uint8_t key; 16*4882a593Smuzhiyun uint8_t action; 17*4882a593Smuzhiyun uint16_t period; /* in milliseconds */ 18*4882a593Smuzhiyun } __attribute__ ((__packed__)); 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun enum kone_keystroke_buttons { 21*4882a593Smuzhiyun kone_keystroke_button_1 = 0xf0, /* left mouse button */ 22*4882a593Smuzhiyun kone_keystroke_button_2 = 0xf1, /* right mouse button */ 23*4882a593Smuzhiyun kone_keystroke_button_3 = 0xf2, /* wheel */ 24*4882a593Smuzhiyun kone_keystroke_button_9 = 0xf3, /* side button up */ 25*4882a593Smuzhiyun kone_keystroke_button_8 = 0xf4 /* side button down */ 26*4882a593Smuzhiyun }; 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun enum kone_keystroke_actions { 29*4882a593Smuzhiyun kone_keystroke_action_press = 0, 30*4882a593Smuzhiyun kone_keystroke_action_release = 1 31*4882a593Smuzhiyun }; 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun struct kone_button_info { 34*4882a593Smuzhiyun uint8_t number; /* range 1-8 */ 35*4882a593Smuzhiyun uint8_t type; 36*4882a593Smuzhiyun uint8_t macro_type; /* 0 = short, 1 = overlong */ 37*4882a593Smuzhiyun uint8_t macro_set_name[16]; /* can be max 15 chars long */ 38*4882a593Smuzhiyun uint8_t macro_name[16]; /* can be max 15 chars long */ 39*4882a593Smuzhiyun uint8_t count; 40*4882a593Smuzhiyun struct kone_keystroke keystrokes[20]; 41*4882a593Smuzhiyun } __attribute__ ((__packed__)); 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun enum kone_button_info_types { 44*4882a593Smuzhiyun /* valid button types until firmware 1.32 */ 45*4882a593Smuzhiyun kone_button_info_type_button_1 = 0x1, /* click (left mouse button) */ 46*4882a593Smuzhiyun kone_button_info_type_button_2 = 0x2, /* menu (right mouse button)*/ 47*4882a593Smuzhiyun kone_button_info_type_button_3 = 0x3, /* scroll (wheel) */ 48*4882a593Smuzhiyun kone_button_info_type_double_click = 0x4, 49*4882a593Smuzhiyun kone_button_info_type_key = 0x5, 50*4882a593Smuzhiyun kone_button_info_type_macro = 0x6, 51*4882a593Smuzhiyun kone_button_info_type_off = 0x7, 52*4882a593Smuzhiyun /* TODO clarify function and rename */ 53*4882a593Smuzhiyun kone_button_info_type_osd_xy_prescaling = 0x8, 54*4882a593Smuzhiyun kone_button_info_type_osd_dpi = 0x9, 55*4882a593Smuzhiyun kone_button_info_type_osd_profile = 0xa, 56*4882a593Smuzhiyun kone_button_info_type_button_9 = 0xb, /* ie forward */ 57*4882a593Smuzhiyun kone_button_info_type_button_8 = 0xc, /* ie backward */ 58*4882a593Smuzhiyun kone_button_info_type_dpi_up = 0xd, /* internal */ 59*4882a593Smuzhiyun kone_button_info_type_dpi_down = 0xe, /* internal */ 60*4882a593Smuzhiyun kone_button_info_type_button_7 = 0xf, /* tilt left */ 61*4882a593Smuzhiyun kone_button_info_type_button_6 = 0x10, /* tilt right */ 62*4882a593Smuzhiyun kone_button_info_type_profile_up = 0x11, /* internal */ 63*4882a593Smuzhiyun kone_button_info_type_profile_down = 0x12, /* internal */ 64*4882a593Smuzhiyun /* additional valid button types since firmware 1.38 */ 65*4882a593Smuzhiyun kone_button_info_type_multimedia_open_player = 0x20, 66*4882a593Smuzhiyun kone_button_info_type_multimedia_next_track = 0x21, 67*4882a593Smuzhiyun kone_button_info_type_multimedia_prev_track = 0x22, 68*4882a593Smuzhiyun kone_button_info_type_multimedia_play_pause = 0x23, 69*4882a593Smuzhiyun kone_button_info_type_multimedia_stop = 0x24, 70*4882a593Smuzhiyun kone_button_info_type_multimedia_mute = 0x25, 71*4882a593Smuzhiyun kone_button_info_type_multimedia_volume_up = 0x26, 72*4882a593Smuzhiyun kone_button_info_type_multimedia_volume_down = 0x27 73*4882a593Smuzhiyun }; 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun enum kone_button_info_numbers { 76*4882a593Smuzhiyun kone_button_top = 1, 77*4882a593Smuzhiyun kone_button_wheel_tilt_left = 2, 78*4882a593Smuzhiyun kone_button_wheel_tilt_right = 3, 79*4882a593Smuzhiyun kone_button_forward = 4, 80*4882a593Smuzhiyun kone_button_backward = 5, 81*4882a593Smuzhiyun kone_button_middle = 6, 82*4882a593Smuzhiyun kone_button_plus = 7, 83*4882a593Smuzhiyun kone_button_minus = 8, 84*4882a593Smuzhiyun }; 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun struct kone_light_info { 87*4882a593Smuzhiyun uint8_t number; /* number of light 1-5 */ 88*4882a593Smuzhiyun uint8_t mod; /* 1 = on, 2 = off */ 89*4882a593Smuzhiyun uint8_t red; /* range 0x00-0xff */ 90*4882a593Smuzhiyun uint8_t green; /* range 0x00-0xff */ 91*4882a593Smuzhiyun uint8_t blue; /* range 0x00-0xff */ 92*4882a593Smuzhiyun } __attribute__ ((__packed__)); 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun struct kone_profile { 95*4882a593Smuzhiyun uint16_t size; /* always 975 */ 96*4882a593Smuzhiyun uint16_t unused; /* always 0 */ 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /* 99*4882a593Smuzhiyun * range 1-5 100*4882a593Smuzhiyun * This number does not need to correspond with location where profile 101*4882a593Smuzhiyun * saved 102*4882a593Smuzhiyun */ 103*4882a593Smuzhiyun uint8_t profile; /* range 1-5 */ 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun uint16_t main_sensitivity; /* range 100-1000 */ 106*4882a593Smuzhiyun uint8_t xy_sensitivity_enabled; /* 1 = on, 2 = off */ 107*4882a593Smuzhiyun uint16_t x_sensitivity; /* range 100-1000 */ 108*4882a593Smuzhiyun uint16_t y_sensitivity; /* range 100-1000 */ 109*4882a593Smuzhiyun uint8_t dpi_rate; /* bit 1 = 800, ... */ 110*4882a593Smuzhiyun uint8_t startup_dpi; /* range 1-6 */ 111*4882a593Smuzhiyun uint8_t polling_rate; /* 1 = 125Hz, 2 = 500Hz, 3 = 1000Hz */ 112*4882a593Smuzhiyun /* kone has no dcu 113*4882a593Smuzhiyun * value is always 2 in firmwares <= 1.32 and 114*4882a593Smuzhiyun * 1 in firmwares > 1.32 115*4882a593Smuzhiyun */ 116*4882a593Smuzhiyun uint8_t dcu_flag; 117*4882a593Smuzhiyun uint8_t light_effect_1; /* range 1-3 */ 118*4882a593Smuzhiyun uint8_t light_effect_2; /* range 1-5 */ 119*4882a593Smuzhiyun uint8_t light_effect_3; /* range 1-4 */ 120*4882a593Smuzhiyun uint8_t light_effect_speed; /* range 0-255 */ 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun struct kone_light_info light_infos[5]; 123*4882a593Smuzhiyun /* offset is kone_button_info_numbers - 1 */ 124*4882a593Smuzhiyun struct kone_button_info button_infos[8]; 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun uint16_t checksum; /* \brief holds checksum of struct */ 127*4882a593Smuzhiyun } __attribute__ ((__packed__)); 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun enum kone_polling_rates { 130*4882a593Smuzhiyun kone_polling_rate_125 = 1, 131*4882a593Smuzhiyun kone_polling_rate_500 = 2, 132*4882a593Smuzhiyun kone_polling_rate_1000 = 3 133*4882a593Smuzhiyun }; 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun struct kone_settings { 136*4882a593Smuzhiyun uint16_t size; /* always 36 */ 137*4882a593Smuzhiyun uint8_t startup_profile; /* 1-5 */ 138*4882a593Smuzhiyun uint8_t unknown1; 139*4882a593Smuzhiyun uint8_t tcu; /* 0 = off, 1 = on */ 140*4882a593Smuzhiyun uint8_t unknown2[23]; 141*4882a593Smuzhiyun uint8_t calibration_data[4]; 142*4882a593Smuzhiyun uint8_t unknown3[2]; 143*4882a593Smuzhiyun uint16_t checksum; 144*4882a593Smuzhiyun } __attribute__ ((__packed__)); 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun /* 147*4882a593Smuzhiyun * 12 byte mouse event read by interrupt_read 148*4882a593Smuzhiyun */ 149*4882a593Smuzhiyun struct kone_mouse_event { 150*4882a593Smuzhiyun uint8_t report_number; /* always 1 */ 151*4882a593Smuzhiyun uint8_t button; 152*4882a593Smuzhiyun uint16_t x; 153*4882a593Smuzhiyun uint16_t y; 154*4882a593Smuzhiyun uint8_t wheel; /* up = 1, down = -1 */ 155*4882a593Smuzhiyun uint8_t tilt; /* right = 1, left = -1 */ 156*4882a593Smuzhiyun uint8_t unknown; 157*4882a593Smuzhiyun uint8_t event; 158*4882a593Smuzhiyun uint8_t value; /* press = 0, release = 1 */ 159*4882a593Smuzhiyun uint8_t macro_key; /* 0 to 8 */ 160*4882a593Smuzhiyun } __attribute__ ((__packed__)); 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun enum kone_mouse_events { 163*4882a593Smuzhiyun /* osd events are thought to be display on screen */ 164*4882a593Smuzhiyun kone_mouse_event_osd_dpi = 0xa0, 165*4882a593Smuzhiyun kone_mouse_event_osd_profile = 0xb0, 166*4882a593Smuzhiyun /* TODO clarify meaning and occurence of kone_mouse_event_calibration */ 167*4882a593Smuzhiyun kone_mouse_event_calibration = 0xc0, 168*4882a593Smuzhiyun kone_mouse_event_call_overlong_macro = 0xe0, 169*4882a593Smuzhiyun kone_mouse_event_multimedia = 0xe1, 170*4882a593Smuzhiyun /* switch events notify if user changed values with mousebutton click */ 171*4882a593Smuzhiyun kone_mouse_event_switch_dpi = 0xf0, 172*4882a593Smuzhiyun kone_mouse_event_switch_profile = 0xf1 173*4882a593Smuzhiyun }; 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun enum kone_commands { 176*4882a593Smuzhiyun kone_command_profile = 0x5a, 177*4882a593Smuzhiyun kone_command_settings = 0x15a, 178*4882a593Smuzhiyun kone_command_firmware_version = 0x25a, 179*4882a593Smuzhiyun kone_command_weight = 0x45a, 180*4882a593Smuzhiyun kone_command_calibrate = 0x55a, 181*4882a593Smuzhiyun kone_command_confirm_write = 0x65a, 182*4882a593Smuzhiyun kone_command_firmware = 0xe5a 183*4882a593Smuzhiyun }; 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun struct kone_roccat_report { 186*4882a593Smuzhiyun uint8_t event; 187*4882a593Smuzhiyun uint8_t value; /* holds dpi or profile value */ 188*4882a593Smuzhiyun uint8_t key; /* macro key on overlong macro execution */ 189*4882a593Smuzhiyun } __attribute__ ((__packed__)); 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun struct kone_device { 192*4882a593Smuzhiyun /* 193*4882a593Smuzhiyun * Storing actual values when we get informed about changes since there 194*4882a593Smuzhiyun * is no way of getting this information from the device on demand 195*4882a593Smuzhiyun */ 196*4882a593Smuzhiyun int actual_profile, actual_dpi; 197*4882a593Smuzhiyun /* Used for neutralizing abnormal button behaviour */ 198*4882a593Smuzhiyun struct kone_mouse_event last_mouse_event; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun /* 201*4882a593Smuzhiyun * It's unlikely that multiple sysfs attributes are accessed at a time, 202*4882a593Smuzhiyun * so only one mutex is used to secure hardware access and profiles and 203*4882a593Smuzhiyun * settings of this struct. 204*4882a593Smuzhiyun */ 205*4882a593Smuzhiyun struct mutex kone_lock; 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun /* 208*4882a593Smuzhiyun * Storing the data here reduces IO and ensures that data is available 209*4882a593Smuzhiyun * when its needed (E.g. interrupt handler). 210*4882a593Smuzhiyun */ 211*4882a593Smuzhiyun struct kone_profile profiles[5]; 212*4882a593Smuzhiyun struct kone_settings settings; 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun /* 215*4882a593Smuzhiyun * firmware doesn't change unless firmware update is implemented, 216*4882a593Smuzhiyun * so it's read only once 217*4882a593Smuzhiyun */ 218*4882a593Smuzhiyun int firmware_version; 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun int roccat_claimed; 221*4882a593Smuzhiyun int chrdev_minor; 222*4882a593Smuzhiyun }; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun #endif 225