aboutsummaryrefslogtreecommitdiff
path: root/drivers/hid/hid-roccat-koneplus.h
blob: 905e33d45354715bb03cd9acf01d781946562f82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#ifndef __HID_ROCCAT_KONEPLUS_H
#define __HID_ROCCAT_KONEPLUS_H

/*
 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 */

#include <linux/types.h>

/*
 * Binary data structures used for hardware communication must have no padding.
 */
#pragma pack(push)
#pragma pack(1)

/*
 * case 1: writes request 80 and reads value 1
 *
 */
struct koneplus_control {
	uint8_t command; /* KONEPLUS_COMMAND_CONTROL */
	/*
	 * value is profile number in range 0-4 for requesting settings and buttons
	 * 1 if status ok for requesting status
	 */
	uint8_t value;
	uint8_t request;
};

enum koneplus_control_requests {
	KONEPLUS_CONTROL_REQUEST_STATUS = 0x00,
	KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
	KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90,
};

enum koneplus_control_values {
	KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0,
	KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1,
	KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3,
};

struct koneplus_startup_profile {
	uint8_t command; /* KONEPLUS_COMMAND_STARTUP_PROFILE */
	uint8_t size; /* always 3 */
	uint8_t startup_profile; /* Range 0-4! */
};

struct koneplus_profile_settings {
	uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */
	uint8_t size; /* always 43 */
	uint8_t number; /* range 0-4 */
	uint8_t advanced_sensitivity;
	uint8_t sensitivity_x;
	uint8_t sensitivity_y;
	uint8_t cpi_levels_enabled;
	uint8_t cpi_levels_x[5];
	uint8_t cpi_startup_level; /* range 0-4 */
	uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */
	uint8_t unknown1;
	uint8_t polling_rate;
	uint8_t lights_enabled;
	uint8_t light_effect_mode;
	uint8_t color_flow_effect;
	uint8_t light_effect_type;
	uint8_t light_effect_speed;
	uint8_t lights[16];
	uint16_t checksum;
};

struct koneplus_profile_buttons {
	uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */
	uint8_t size; /* always 77 */
	uint8_t number; /* range 0-4 */
	uint8_t data[72];
	uint16_t checksum;
};

struct koneplus_macro {
	uint8_t command; /* KONEPLUS_COMMAND_MACRO */
	uint16_t size; /* always 0x822 little endian */
	uint8_t profile; /* range 0-4 */
	uint8_t button; /* range 0-23 */
	uint8_t data[2075];
	uint16_t checksum;
};

struct koneplus_info {
	uint8_t command; /* KONEPLUS_COMMAND_INFO */
	uint8_t size; /* always 6 */
	uint8_t firmware_version;
	uint8_t unknown[3];
};

struct koneplus_e {
	uint8_t command; /* KONEPLUS_COMMAND_E */
	uint8_t size; /* always 3 */
	uint8_t unknown; /* TODO 1; 0 before firmware update */
};

struct koneplus_sensor {
	uint8_t command;  /* KONEPLUS_COMMAND_SENSOR */
	uint8_t size; /* always 6 */
	uint8_t data[4];
};

struct koneplus_firmware_write {
	uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */
	uint8_t unknown[1025];
};

struct koneplus_firmware_write_control {
	uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */
	/*
	 * value is 1 on success
	 * 3 means "not finished yet"
	 */
	uint8_t value;
	uint8_t unknown; /* always 0x75 */
};

struct koneplus_tcu {
	uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
	uint8_t data[2];
};

struct koneplus_tcu_image {
	uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
	uint8_t data[1024];
	uint16_t checksum;
};

enum koneplus_commands {
	KONEPLUS_COMMAND_CONTROL = 0x4,
	KONEPLUS_COMMAND_STARTUP_PROFILE = 0x5,
	KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
	KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
	KONEPLUS_COMMAND_MACRO = 0x8,
	KONEPLUS_COMMAND_INFO = 0x9,
	KONEPLUS_COMMAND_E = 0xe,
	KONEPLUS_COMMAND_SENSOR = 0xf,
	KONEPLUS_COMMAND_FIRMWARE_WRITE = 0x1b,
	KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c,
};

enum koneplus_usb_commands {
	KONEPLUS_USB_COMMAND_CONTROL = 0x304,
	KONEPLUS_USB_COMMAND_STARTUP_PROFILE = 0x305,
	KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306,
	KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307,
	KONEPLUS_USB_COMMAND_MACRO = 0x308,
	KONEPLUS_USB_COMMAND_INFO = 0x309,
	KONEPLUS_USB_COMMAND_TCU = 0x30c,
	KONEPLUS_USB_COMMAND_E = 0x30e,
	KONEPLUS_USB_COMMAND_SENSOR = 0x30f,
	KONEPLUS_USB_COMMAND_FIRMWARE_WRITE = 0x31b,
	KONEPLUS_USB_COMMAND_FIRMWARE_WRITE_CONTROL = 0x31c,
};

enum koneplus_mouse_report_numbers {
	KONEPLUS_MOUSE_REPORT_NUMBER_HID = 1,
	KONEPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2,
	KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON = 3,
};

struct koneplus_mouse_report_button {
	uint8_t report_number; /* always KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON */
	uint8_t zero1;
	uint8_t type;
	uint8_t data1;
	uint8_t data2;
	uint8_t zero2;
	uint8_t unknown[2];
};

enum koneplus_mouse_report_button_types {
	/* data1 = new profile range 1-5 */
	KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE = 0x20,

	/* data1 = button number range 1-24; data2 = action */
	KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60,

	/* data1 = button number range 1-24; data2 = action */
	KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80,

	/* data1 = setting number range 1-5 */
	KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0,

	/* data1 and data2 = range 0x1-0xb */
	KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0,

	/* data1 = 22 = next track...
	 * data2 = action
	 */
	KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
};

enum koneplus_mouse_report_button_action {
	KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS = 0,
	KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_RELEASE = 1,
};

struct koneplus_roccat_report {
	uint8_t type;
	uint8_t data1;
	uint8_t data2;
	uint8_t profile;
};

#pragma pack(pop)

struct koneplus_device {
	int actual_profile;

	int roccat_claimed;
	int chrdev_minor;

	struct mutex koneplus_lock;

	int startup_profile;
	struct koneplus_info info;
	struct koneplus_profile_settings profile_settings[5];
	struct koneplus_profile_buttons profile_buttons[5];
};

#endif