Skip to content

Commit dd90193

Browse files
flukejonesKyleGospo
authored andcommitted
[FOR-UPSTREAM] hid-asus-ally: add calibrations (wip)
Signed-off-by: Luke D. Jones <luke@ljones.dev>
1 parent fcb6cb8 commit dd90193

1 file changed

Lines changed: 95 additions & 0 deletions

File tree

drivers/hid/hid-asus-ally.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,28 @@ struct response_curve {
275275
uint8_t response_pct_4;
276276
} __packed;
277277

278+
struct js_axis_calibrations {
279+
uint16_t left_y_stable;
280+
uint16_t left_y_min;
281+
uint16_t left_y_max;
282+
uint16_t left_x_stable;
283+
uint16_t left_x_min;
284+
uint16_t left_x_max;
285+
uint16_t right_y_stable;
286+
uint16_t right_y_min;
287+
uint16_t right_y_max;
288+
uint16_t right_x_stable;
289+
uint16_t right_x_min;
290+
uint16_t right_x_max;
291+
} __packed;
292+
293+
struct tr_axis_calibrations {
294+
uint16_t left_stable;
295+
uint16_t left_max;
296+
uint16_t right_stable;
297+
uint16_t right_max;
298+
} __packed;
299+
278300
/* ROG Ally has many settings related to the gamepad, all using the same n-key endpoint */
279301
struct ally_gamepad_cfg {
280302
struct hid_device *hdev;
@@ -302,6 +324,9 @@ struct ally_gamepad_cfg {
302324
/* joystick response curves */
303325
struct response_curve ls_rc;
304326
struct response_curve rs_rc;
327+
328+
struct js_axis_calibrations js_cal;
329+
struct tr_axis_calibrations tr_cal;
305330
};
306331

307332
/* The hatswitch outputs integers, we use them to index this X|Y pair */
@@ -380,6 +405,18 @@ static struct ally_drvdata {
380405
uint mcu_version;
381406
} drvdata;
382407

408+
static void reverse_bytes_in_pairs(u8 *buf, size_t size) {
409+
uint16_t *word_ptr;
410+
size_t i;
411+
412+
for (i = 0; i < size; i += 2) {
413+
if (i + 1 < size) {
414+
word_ptr = (uint16_t *)&buf[i];
415+
*word_ptr = cpu_to_be16(*word_ptr);
416+
}
417+
}
418+
}
419+
383420
/**
384421
* asus_dev_set_report - send set report request to device.
385422
*
@@ -804,6 +841,63 @@ ALLY_JS_RC_POINT(axis_xy_right, response, 2);
804841
ALLY_JS_RC_POINT(axis_xy_right, response, 3);
805842
ALLY_JS_RC_POINT(axis_xy_right, response, 4);
806843

844+
/* CALIBRATIONS ***********************************************************************************/
845+
static int gamepad_get_calibration(struct hid_device *hdev)
846+
{
847+
struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
848+
u8 *hidbuf;
849+
int ret, i;
850+
851+
if (!drvdata.gamepad_cfg)
852+
return -ENODEV;
853+
854+
hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
855+
if (!hidbuf)
856+
return -ENOMEM;
857+
858+
for (i = 0; i < 2; i++) {
859+
hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
860+
hidbuf[1] = 0xD0;
861+
hidbuf[2] = 0x03;
862+
hidbuf[3] = i + 1; // 0x01 JS, 0x02 TR
863+
hidbuf[4] = 0x20;
864+
865+
ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
866+
if (ret < 0) {
867+
hid_warn(hdev, "ROG Ally check failed set report: %d\n", ret);
868+
goto cleanup;
869+
}
870+
871+
memset(hidbuf, 0, FEATURE_ROG_ALLY_REPORT_SIZE);
872+
ret = asus_dev_get_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
873+
if (ret < 0 || hidbuf[5] != 1) {
874+
hid_warn(hdev, "ROG Ally check failed get report: %d\n", ret);
875+
goto cleanup;
876+
}
877+
878+
if (i == 0) {
879+
/* Joystick calibration */
880+
reverse_bytes_in_pairs(&hidbuf[6], sizeof(struct js_axis_calibrations));
881+
ally_cfg->js_cal = *(struct js_axis_calibrations *)&hidbuf[6];
882+
print_hex_dump(KERN_INFO, "HID Buffer JS: ", DUMP_PREFIX_OFFSET, 16, 1, hidbuf, 32, true);
883+
struct js_axis_calibrations *cal = &drvdata.gamepad_cfg->js_cal;
884+
pr_err("LS_CAL: X: %d, Min: %d, Max: %d", cal->left_x_stable, cal->left_x_min, cal->left_x_max);
885+
pr_err("LS_CAL: Y: %d, Min: %d, Max: %d", cal->left_y_stable, cal->left_y_min, cal->left_y_max);
886+
pr_err("RS_CAL: X: %d, Min: %d, Max: %d", cal->right_x_stable, cal->right_x_min, cal->right_x_max);
887+
pr_err("RS_CAL: Y: %d, Min: %d, Max: %d", cal->right_y_stable, cal->right_y_min, cal->right_y_max);
888+
} else {
889+
/* Trigger calibration */
890+
reverse_bytes_in_pairs(&hidbuf[6], sizeof(struct tr_axis_calibrations));
891+
ally_cfg->tr_cal = *(struct tr_axis_calibrations *)&hidbuf[6];
892+
print_hex_dump(KERN_INFO, "HID Buffer TR: ", DUMP_PREFIX_OFFSET, 16, 1, hidbuf, 32, true);
893+
}
894+
}
895+
896+
cleanup:
897+
kfree(hidbuf);
898+
return ret;
899+
}
900+
807901
static struct attribute *axis_xy_left_attrs[] = {
808902
&dev_attr_axis_xy_left_anti_deadzone.attr,
809903
&dev_attr_axis_xy_left_deadzone.attr,
@@ -1283,6 +1377,7 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
12831377
ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m1.button = BTN_KB_M1;
12841378
ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m2.button = BTN_KB_M2;
12851379
_gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_m1_m2);
1380+
gamepad_get_calibration(hdev);
12861381

12871382
ally_cfg->vibration_intensity[0] = 0x64;
12881383
ally_cfg->vibration_intensity[1] = 0x64;

0 commit comments

Comments
 (0)