Skip to content

Commit 36f57a0

Browse files
flukejonesKyleGospo
authored andcommitted
[FOR-UPSTREAM] hid-asus-ally: add JS response curves
Signed-off-by: Luke D. Jones <luke@ljones.dev>
1 parent 6016153 commit 36f57a0

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

drivers/hid/hid-asus-ally.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
* Copyright (c) 2023 Luke Jones <luke@ljones.dev>
66
*/
77

8+
#include "linux/compiler_attributes.h"
89
#include "linux/device.h"
910
#include <linux/platform_data/x86/asus-wmi.h>
1011
#include <linux/platform_device.h>
1112
#include "linux/pm.h"
13+
#include "linux/printk.h"
1214
#include "linux/slab.h"
1315
#include <linux/hid.h>
1416
#include <linux/types.h>
@@ -262,6 +264,17 @@ struct deadzone {
262264
u8 outer;
263265
};
264266

267+
struct response_curve {
268+
uint8_t move_pct_1;
269+
uint8_t response_pct_1;
270+
uint8_t move_pct_2;
271+
uint8_t response_pct_2;
272+
uint8_t move_pct_3;
273+
uint8_t response_pct_3;
274+
uint8_t move_pct_4;
275+
uint8_t response_pct_4;
276+
} __packed;
277+
265278
/* ROG Ally has many settings related to the gamepad, all using the same n-key endpoint */
266279
struct ally_gamepad_cfg {
267280
struct hid_device *hdev;
@@ -286,6 +299,9 @@ struct ally_gamepad_cfg {
286299
/* anti-deadzones */
287300
u8 ls_adz; // left stick
288301
u8 rs_adz; // right stick
302+
/* joystick response curves */
303+
struct response_curve ls_rc;
304+
struct response_curve rs_rc;
289305
};
290306

291307
/* The hatswitch outputs integers, we use them to index this X|Y pair */
@@ -720,10 +736,85 @@ static ssize_t axis_xy_right_anti_deadzone_store(struct device *dev,
720736
}
721737
ALLY_DEVICE_ATTR_RW(axis_xy_right_anti_deadzone, anti_deadzone);
722738

739+
/* JS RESPONSE CURVES *****************************************************************************/
740+
static void _gamepad_set_js_response_curves_default(struct ally_gamepad_cfg *ally_cfg)
741+
{
742+
struct response_curve *js1_rc = &ally_cfg->ls_rc;
743+
struct response_curve *js2_rc = &ally_cfg->rs_rc;
744+
js1_rc->move_pct_1 = js2_rc->move_pct_1 = 0x16; // 25%
745+
js1_rc->move_pct_2 = js2_rc->move_pct_2 = 0x32; // 50%
746+
js1_rc->move_pct_3 = js2_rc->move_pct_3 = 0x48; // 75%
747+
js1_rc->move_pct_4 = js2_rc->move_pct_4 = 0x64; // 100%
748+
js1_rc->response_pct_1 = js2_rc->response_pct_1 = 0x16;
749+
js1_rc->response_pct_2 = js2_rc->response_pct_2 = 0x32;
750+
js1_rc->response_pct_3 = js2_rc->response_pct_3 = 0x48;
751+
js1_rc->response_pct_4 = js2_rc->response_pct_4 = 0x64;
752+
}
753+
754+
static ssize_t _gamepad_apply_response_curves(struct hid_device *hdev,
755+
struct ally_gamepad_cfg *ally_cfg)
756+
{
757+
u8 *hidbuf;
758+
int ret;
759+
760+
hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
761+
if (!hidbuf)
762+
return -ENOMEM;
763+
764+
hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
765+
hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
766+
memcpy(&hidbuf[2], &ally_cfg->ls_rc, sizeof(ally_cfg->ls_rc));
767+
768+
ret = ally_gamepad_check_ready(hdev);
769+
if (ret < 0)
770+
goto report_fail;
771+
772+
hidbuf[4] = 0x02;
773+
memcpy(&hidbuf[5], &ally_cfg->rs_rc, sizeof(ally_cfg->rs_rc));
774+
775+
ret = ally_gamepad_check_ready(hdev);
776+
if (ret < 0)
777+
goto report_fail;
778+
779+
ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
780+
if (ret < 0)
781+
goto report_fail;
782+
783+
report_fail:
784+
kfree(hidbuf);
785+
return ret;
786+
}
787+
788+
ALLY_JS_RC_POINT(axis_xy_left, move, 1);
789+
ALLY_JS_RC_POINT(axis_xy_left, move, 2);
790+
ALLY_JS_RC_POINT(axis_xy_left, move, 3);
791+
ALLY_JS_RC_POINT(axis_xy_left, move, 4);
792+
ALLY_JS_RC_POINT(axis_xy_left, response, 1);
793+
ALLY_JS_RC_POINT(axis_xy_left, response, 2);
794+
ALLY_JS_RC_POINT(axis_xy_left, response, 3);
795+
ALLY_JS_RC_POINT(axis_xy_left, response, 4);
796+
797+
ALLY_JS_RC_POINT(axis_xy_right, move, 1);
798+
ALLY_JS_RC_POINT(axis_xy_right, move, 2);
799+
ALLY_JS_RC_POINT(axis_xy_right, move, 3);
800+
ALLY_JS_RC_POINT(axis_xy_right, move, 4);
801+
ALLY_JS_RC_POINT(axis_xy_right, response, 1);
802+
ALLY_JS_RC_POINT(axis_xy_right, response, 2);
803+
ALLY_JS_RC_POINT(axis_xy_right, response, 3);
804+
ALLY_JS_RC_POINT(axis_xy_right, response, 4);
805+
723806
static struct attribute *axis_xy_left_attrs[] = {
724807
&dev_attr_axis_xy_left_anti_deadzone.attr,
725808
&dev_attr_axis_xy_left_deadzone.attr,
726809
&dev_attr_axis_xyz_deadzone_index.attr,
810+
&dev_attr_axis_xy_left_move_1.attr,
811+
&dev_attr_axis_xy_left_move_2.attr,
812+
&dev_attr_axis_xy_left_move_3.attr,
813+
&dev_attr_axis_xy_left_move_4.attr,
814+
&dev_attr_axis_xy_left_response_1.attr,
815+
&dev_attr_axis_xy_left_response_2.attr,
816+
&dev_attr_axis_xy_left_response_3.attr,
817+
&dev_attr_axis_xy_left_response_4.attr,
727818
NULL
728819
};
729820
static const struct attribute_group axis_xy_left_attr_group = {
@@ -735,6 +826,14 @@ static struct attribute *axis_xy_right_attrs[] = {
735826
&dev_attr_axis_xy_right_anti_deadzone.attr,
736827
&dev_attr_axis_xy_right_deadzone.attr,
737828
&dev_attr_axis_xyz_deadzone_index.attr,
829+
&dev_attr_axis_xy_right_move_1.attr,
830+
&dev_attr_axis_xy_right_move_2.attr,
831+
&dev_attr_axis_xy_right_move_3.attr,
832+
&dev_attr_axis_xy_right_move_4.attr,
833+
&dev_attr_axis_xy_right_response_1.attr,
834+
&dev_attr_axis_xy_right_response_2.attr,
835+
&dev_attr_axis_xy_right_response_3.attr,
836+
&dev_attr_axis_xy_right_response_4.attr,
738837
NULL
739838
};
740839
static const struct attribute_group axis_xy_right_attr_group = {
@@ -930,6 +1029,9 @@ static ssize_t _gamepad_apply_all(struct hid_device *hdev, struct ally_gamepad_c
9301029
if (ret < 0)
9311030
return ret;
9321031
ret = _gamepad_apply_js_ADZ(hdev, ally_cfg);
1032+
if (ret < 0)
1033+
return ret;
1034+
ret =_gamepad_apply_response_curves(hdev, ally_cfg);
9331035
if (ret < 0)
9341036
return ret;
9351037

@@ -1177,6 +1279,7 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
11771279
ally_cfg->vibration_intensity[1] = 0x64;
11781280
_gamepad_set_deadzones_default(ally_cfg);
11791281
_gamepad_set_anti_deadzones_default(ally_cfg);
1282+
_gamepad_set_js_response_curves_default(ally_cfg);
11801283

11811284
drvdata.gamepad_cfg = ally_cfg; // Must asign before attr group setup
11821285
if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {

drivers/hid/hid-asus-ally.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum xpad_cmd {
2828
xpad_cmd_set_leds = 0x08,
2929
xpad_cmd_check_ready = 0x0A,
3030
xpad_cmd_set_turbo = 0x0F,
31+
xpad_cmd_set_response_curve = 0x13,
3132
xpad_cmd_set_adz = 0x18,
3233
};
3334

@@ -39,6 +40,7 @@ enum xpad_cmd_len {
3940
xpad_cmd_len_vibe_intensity = 0x02,
4041
xpad_cmd_len_leds = 0x0C,
4142
xpad_cmd_len_turbo = 0x20,
43+
xpad_cmd_len_response_curve = 0x09,
4244
xpad_cmd_len_adz = 0x02,
4345
};
4446

@@ -309,6 +311,42 @@ enum btn_pair_index {
309311
ALLY_DEADZONE_STORE(_fname##_deadzone, _mname); \
310312
ALLY_DEVICE_ATTR_RW(_fname##_deadzone, deadzone)
311313

314+
/* response curve macros */
315+
#define ALLY_RESP_CURVE_SHOW(_fname, _mname) \
316+
static ssize_t _fname##_show(struct device *dev, \
317+
struct device_attribute *attr, \
318+
char *buf) \
319+
{ \
320+
struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
321+
if (!drvdata.gamepad_cfg) \
322+
return -ENODEV; \
323+
return sysfs_emit(buf, "%d\n", ally_cfg->ls_rc._mname); \
324+
}
325+
326+
#define ALLY_RESP_CURVE_STORE(_fname, _mname) \
327+
static ssize_t _fname##_store(struct device *dev, \
328+
struct device_attribute *attr, \
329+
const char *buf, size_t count) \
330+
{ \
331+
struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg; \
332+
int ret, val; \
333+
if (!drvdata.gamepad_cfg) \
334+
return -ENODEV; \
335+
ret = kstrtoint(buf, 0, &val); \
336+
if (ret) \
337+
return ret; \
338+
if (val < 0 || val > 100) \
339+
return -EINVAL; \
340+
ally_cfg->ls_rc._mname = val; \
341+
return count; \
342+
}
343+
344+
/* _point_n must start at 1 */
345+
#define ALLY_JS_RC_POINT(_fname, _mname, _num) \
346+
ALLY_RESP_CURVE_SHOW(_fname##_##_mname##_##_num, _mname##_pct_##_num); \
347+
ALLY_RESP_CURVE_STORE(_fname##_##_mname##_##_num, _mname##_pct_##_num); \
348+
ALLY_DEVICE_ATTR_RW(_fname##_##_mname##_##_num, curve_##_mname##_pct_##_num)
349+
312350
#define ALLY_BTN_ATTRS_GROUP(_name, _fname) \
313351
static struct attribute *_fname##_attrs[] = { \
314352
&dev_attr_##_fname.attr, \

0 commit comments

Comments
 (0)