@@ -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 */
279301struct 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);
804841ALLY_JS_RC_POINT (axis_xy_right , response , 3 );
805842ALLY_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+
807901static 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