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
|
From ebde4075918ad7a2db7499329f4f4c1e22ee3c5a Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
Date: Sat, 5 Oct 2024 20:46:00 +1300
Subject: [PATCH 13/29] hid-asus-ally: add vibration intensity settings
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
drivers/hid/hid-asus-ally.c | 93 +++++++++++++++++++++++++++++++++++++
drivers/hid/hid-asus-ally.h | 6 +++
2 files changed, 99 insertions(+)
diff --git a/drivers/hid/hid-asus-ally.c b/drivers/hid/hid-asus-ally.c
index 53c2b36c14fb..8b40b806631c 100644
--- a/drivers/hid/hid-asus-ally.c
+++ b/drivers/hid/hid-asus-ally.c
@@ -270,6 +270,11 @@ struct ally_gamepad_cfg {
* index: [mode]
*/
struct btn_mapping key_mapping[xpad_mode_mouse];
+ /*
+ * index: left, right
+ * max: 64
+ */
+ u8 vibration_intensity[2];
};
/* The hatswitch outputs integers, we use them to index this X|Y pair */
@@ -441,6 +446,89 @@ static int ally_gamepad_check_ready(struct hid_device *hdev)
return ret;
}
+/* VIBRATION INTENSITY ****************************************************************************/
+static ssize_t gamepad_vibration_intensity_index_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "left right\n");
+}
+
+ALLY_DEVICE_ATTR_RO(gamepad_vibration_intensity_index, vibration_intensity_index);
+
+static ssize_t _gamepad_apply_intensity(struct hid_device *hdev,
+ struct ally_gamepad_cfg *ally_cfg)
+{
+ u8 *hidbuf;
+ int ret;
+
+ hidbuf = kzalloc(FEATURE_ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
+ if (!hidbuf)
+ return -ENOMEM;
+
+ hidbuf[0] = FEATURE_ROG_ALLY_REPORT_ID;
+ hidbuf[1] = FEATURE_ROG_ALLY_CODE_PAGE;
+ hidbuf[2] = xpad_cmd_set_vibe_intensity;
+ hidbuf[3] = xpad_cmd_len_vibe_intensity;
+ hidbuf[4] = ally_cfg->vibration_intensity[0];
+ hidbuf[5] = ally_cfg->vibration_intensity[1];
+
+ ret = ally_gamepad_check_ready(hdev);
+ if (ret < 0)
+ goto report_fail;
+
+ ret = asus_dev_set_report(hdev, hidbuf, FEATURE_ROG_ALLY_REPORT_SIZE);
+ if (ret < 0)
+ goto report_fail;
+
+report_fail:
+ kfree(hidbuf);
+ return ret;
+}
+
+static ssize_t gamepad_vibration_intensity_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
+
+ if (!drvdata.gamepad_cfg)
+ return -ENODEV;
+
+ return sysfs_emit(
+ buf, "%d %d\n",
+ ally_cfg->vibration_intensity[0],
+ ally_cfg->vibration_intensity[1]);
+}
+
+static ssize_t gamepad_vibration_intensity_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = to_hid_device(dev);
+ struct ally_gamepad_cfg *ally_cfg = drvdata.gamepad_cfg;
+ u32 left, right;
+ int ret;
+
+ if (!drvdata.gamepad_cfg)
+ return -ENODEV;
+
+ if (sscanf(buf, "%d %d", &left, &right) != 2)
+ return -EINVAL;
+
+ if (left > 64 || right > 64)
+ return -EINVAL;
+
+ ally_cfg->vibration_intensity[0] = left;
+ ally_cfg->vibration_intensity[1] = right;
+
+ ret = _gamepad_apply_intensity(hdev, ally_cfg);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+ALLY_DEVICE_ATTR_RW(gamepad_vibration_intensity, vibration_intensity);
+
/* A HID packet conatins mappings for two buttons: btn1, btn1_macro, btn2, btn2_macro */
static void _btn_pair_to_hid_pkt(struct ally_gamepad_cfg *ally_cfg,
enum btn_pair_index pair,
@@ -768,6 +856,8 @@ static struct attribute *gamepad_device_attrs[] = {
&dev_attr_btn_mapping_reset.attr,
&dev_attr_gamepad_mode.attr,
&dev_attr_gamepad_apply_all.attr,
+ &dev_attr_gamepad_vibration_intensity.attr,
+ &dev_attr_gamepad_vibration_intensity_index.attr,
NULL
};
@@ -840,6 +930,9 @@ static struct ally_gamepad_cfg *ally_gamepad_cfg_create(struct hid_device *hdev)
ally_cfg->key_mapping[ally_cfg->mode - 1].btn_m2.button = BTN_KB_M2;
_gamepad_apply_btn_pair(hdev, ally_cfg, btn_pair_m1_m2);
+ ally_cfg->vibration_intensity[0] = 0x64;
+ ally_cfg->vibration_intensity[1] = 0x64;
+
drvdata.gamepad_cfg = ally_cfg; // Must asign before attr group setup
if (sysfs_create_groups(&hdev->dev.kobj, gamepad_device_attr_groups)) {
err = -ENODEV;
diff --git a/drivers/hid/hid-asus-ally.h b/drivers/hid/hid-asus-ally.h
index 63a3b5caa71c..6ac79ad3c5f2 100644
--- a/drivers/hid/hid-asus-ally.h
+++ b/drivers/hid/hid-asus-ally.h
@@ -22,6 +22,7 @@ enum xpad_mode {
enum xpad_cmd {
xpad_cmd_set_mode = 0x01,
xpad_cmd_set_mapping = 0x02,
+ xpad_cmd_set_vibe_intensity = 0x06,
xpad_cmd_set_leds = 0x08,
xpad_cmd_check_ready = 0x0A,
xpad_cmd_set_turbo = 0x0F,
@@ -31,6 +32,7 @@ enum xpad_cmd {
enum xpad_cmd_len {
xpad_cmd_len_mode = 0x01,
xpad_cmd_len_mapping = 0x2c,
+ xpad_cmd_len_vibe_intensity = 0x02,
xpad_cmd_len_leds = 0x0C,
xpad_cmd_len_turbo = 0x20,
};
@@ -196,6 +198,10 @@ enum btn_pair_index {
struct device_attribute dev_attr_##_name = \
__ATTR(_sysfs_name, 0644, _name##_show, _name##_store)
+#define ALLY_DEVICE_ATTR_RO(_name, _sysfs_name) \
+ struct device_attribute dev_attr_##_name = \
+ __ATTR(_sysfs_name, 0444, _name##_show, NULL)
+
/* button specific macros */
#define ALLY_BTN_SHOW(_fname, _btn_name, _secondary) \
static ssize_t _fname##_show(struct device *dev, \
--
2.48.1
|