Skip to content

Commit c81760b

Browse files
jwrdegoedeJiri Kosina
authored andcommitted
HID: asus: Parameterize the touchpad code
Instead of having hardcoded (#define-d) values use a struct describing the various touchpad parameters. This is a preparation patch for improving the T100TA touchpad support as well as for adding T100CHI touchpad support. Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 57573c5 commit c81760b

File tree

1 file changed

+67
-47
lines changed

1 file changed

+67
-47
lines changed

drivers/hid/hid-asus.c

Lines changed: 67 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,13 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
4444
#define FEATURE_REPORT_ID 0x0d
4545
#define INPUT_REPORT_ID 0x5d
4646
#define FEATURE_KBD_REPORT_ID 0x5a
47-
48-
#define INPUT_REPORT_SIZE 28
4947
#define FEATURE_KBD_REPORT_SIZE 16
5048

5149
#define SUPPORT_KBD_BACKLIGHT BIT(0)
5250

53-
#define MAX_CONTACTS 5
54-
55-
#define MAX_X 2794
56-
#define MAX_X_T100 2240
57-
#define MAX_Y 1758
5851
#define MAX_TOUCH_MAJOR 8
5952
#define MAX_PRESSURE 128
6053

61-
#define CONTACT_DATA_SIZE 5
62-
6354
#define BTN_LEFT_MASK 0x01
6455
#define CONTACT_TOOL_TYPE_MASK 0x80
6556
#define CONTACT_X_MSB_MASK 0xf0
@@ -74,12 +65,11 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
7465
#define QUIRK_NO_CONSUMER_USAGES BIT(4)
7566
#define QUIRK_USE_KBD_BACKLIGHT BIT(5)
7667
#define QUIRK_T100_KEYBOARD BIT(6)
77-
#define QUIRK_T100_TOUCHPAD BIT(7)
7868

7969
#define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
8070
QUIRK_NO_INIT_REPORTS | \
8171
QUIRK_NO_CONSUMER_USAGES)
82-
#define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
72+
#define I2C_TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
8373
QUIRK_SKIP_INPUT_MAPPING | \
8474
QUIRK_IS_MULTITOUCH)
8575

@@ -93,19 +83,43 @@ struct asus_kbd_leds {
9383
bool removed;
9484
};
9585

86+
struct asus_touchpad_info {
87+
int max_x;
88+
int max_y;
89+
int contact_size;
90+
int max_contacts;
91+
};
92+
9693
struct asus_drvdata {
9794
unsigned long quirks;
9895
struct input_dev *input;
9996
struct asus_kbd_leds *kbd_backlight;
97+
const struct asus_touchpad_info *tp;
10098
bool enable_backlight;
10199
};
102100

103-
static void asus_report_contact_down(struct input_dev *input,
101+
static const struct asus_touchpad_info asus_i2c_tp = {
102+
.max_x = 2794,
103+
.max_y = 1758,
104+
.contact_size = 5,
105+
.max_contacts = 5,
106+
};
107+
108+
static const struct asus_touchpad_info asus_t100ta_tp = {
109+
.max_x = 2240,
110+
.max_y = 1758,
111+
.contact_size = 5,
112+
.max_contacts = 5,
113+
};
114+
115+
static void asus_report_contact_down(struct asus_drvdata *drvdat,
104116
int toolType, u8 *data)
105117
{
106-
int touch_major, pressure;
107-
int x = (data[0] & CONTACT_X_MSB_MASK) << 4 | data[1];
108-
int y = MAX_Y - ((data[0] & CONTACT_Y_MSB_MASK) << 8 | data[2]);
118+
struct input_dev *input = drvdat->input;
119+
int touch_major, pressure, x, y;
120+
121+
x = (data[0] & CONTACT_X_MSB_MASK) << 4 | data[1];
122+
y = drvdat->tp->max_y - ((data[0] & CONTACT_Y_MSB_MASK) << 8 | data[2]);
109123

110124
if (toolType == MT_TOOL_PALM) {
111125
touch_major = MAX_TOUCH_MAJOR;
@@ -122,9 +136,9 @@ static void asus_report_contact_down(struct input_dev *input,
122136
}
123137

124138
/* Required for Synaptics Palm Detection */
125-
static void asus_report_tool_width(struct input_dev *input)
139+
static void asus_report_tool_width(struct asus_drvdata *drvdat)
126140
{
127-
struct input_mt *mt = input->mt;
141+
struct input_mt *mt = drvdat->input->mt;
128142
struct input_mt_slot *oldest;
129143
int oldid, count, i;
130144

@@ -146,48 +160,49 @@ static void asus_report_tool_width(struct input_dev *input)
146160
}
147161

148162
if (oldest) {
149-
input_report_abs(input, ABS_TOOL_WIDTH,
163+
input_report_abs(drvdat->input, ABS_TOOL_WIDTH,
150164
input_mt_get_value(oldest, ABS_MT_TOUCH_MAJOR));
151165
}
152166
}
153167

154-
static void asus_report_input(struct input_dev *input, u8 *data)
168+
static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size)
155169
{
156170
int i;
157171
u8 *contactData = data + 2;
158172

159-
for (i = 0; i < MAX_CONTACTS; i++) {
173+
if (size != 3 + drvdat->tp->contact_size * drvdat->tp->max_contacts)
174+
return 0;
175+
176+
for (i = 0; i < drvdat->tp->max_contacts; i++) {
160177
bool down = !!(data[1] & BIT(i+3));
161178
int toolType = contactData[3] & CONTACT_TOOL_TYPE_MASK ?
162179
MT_TOOL_PALM : MT_TOOL_FINGER;
163180

164-
input_mt_slot(input, i);
165-
input_mt_report_slot_state(input, toolType, down);
181+
input_mt_slot(drvdat->input, i);
182+
input_mt_report_slot_state(drvdat->input, toolType, down);
166183

167184
if (down) {
168-
asus_report_contact_down(input, toolType, contactData);
169-
contactData += CONTACT_DATA_SIZE;
185+
asus_report_contact_down(drvdat, toolType, contactData);
186+
contactData += drvdat->tp->contact_size;
170187
}
171188
}
172189

173-
input_report_key(input, BTN_LEFT, data[1] & BTN_LEFT_MASK);
174-
asus_report_tool_width(input);
190+
input_report_key(drvdat->input, BTN_LEFT, data[1] & BTN_LEFT_MASK);
191+
asus_report_tool_width(drvdat);
192+
193+
input_mt_sync_frame(drvdat->input);
194+
input_sync(drvdat->input);
175195

176-
input_mt_sync_frame(input);
177-
input_sync(input);
196+
return 1;
178197
}
179198

180199
static int asus_raw_event(struct hid_device *hdev,
181200
struct hid_report *report, u8 *data, int size)
182201
{
183202
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
184203

185-
if (drvdata->quirks & QUIRK_IS_MULTITOUCH &&
186-
data[0] == INPUT_REPORT_ID &&
187-
size == INPUT_REPORT_SIZE) {
188-
asus_report_input(drvdata->input, data);
189-
return 1;
190-
}
204+
if (drvdata->tp && data[0] == INPUT_REPORT_ID)
205+
return asus_report_input(drvdata, data, size);
191206

192207
return 0;
193208
}
@@ -339,22 +354,22 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
339354
struct input_dev *input = hi->input;
340355
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
341356

342-
if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
357+
if (drvdata->tp) {
343358
int ret;
344359

345-
if (drvdata->quirks & QUIRK_T100_TOUCHPAD)
346-
input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X_T100, 0, 0);
347-
else
348-
input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0);
349-
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0);
360+
input_set_abs_params(input, ABS_MT_POSITION_X, 0,
361+
drvdata->tp->max_x, 0, 0);
362+
input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
363+
drvdata->tp->max_y, 0, 0);
350364
input_set_abs_params(input, ABS_TOOL_WIDTH, 0, MAX_TOUCH_MAJOR, 0, 0);
351365
input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, MAX_TOUCH_MAJOR, 0, 0);
352366
input_set_abs_params(input, ABS_MT_PRESSURE, 0, MAX_PRESSURE, 0, 0);
353367

354368
__set_bit(BTN_LEFT, input->keybit);
355369
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
356370

357-
ret = input_mt_init_slots(input, MAX_CONTACTS, INPUT_MT_POINTER);
371+
ret = input_mt_init_slots(input, drvdata->tp->max_contacts,
372+
INPUT_MT_POINTER);
358373

359374
if (ret) {
360375
hid_err(hdev, "Asus input mt init slots failed: %d\n", ret);
@@ -504,7 +519,7 @@ static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
504519
{
505520
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
506521

507-
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
522+
if (drvdata->tp)
508523
return asus_start_multitouch(hdev);
509524

510525
return 0;
@@ -525,11 +540,16 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
525540

526541
drvdata->quirks = id->driver_data;
527542

543+
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
544+
drvdata->tp = &asus_i2c_tp;
545+
528546
if (drvdata->quirks & QUIRK_T100_KEYBOARD) {
529547
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
530548

531-
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF)
532-
drvdata->quirks = TOUCHPAD_QUIRKS | QUIRK_T100_TOUCHPAD;
549+
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
550+
drvdata->quirks = QUIRK_SKIP_INPUT_MAPPING;
551+
drvdata->tp = &asus_t100ta_tp;
552+
}
533553
}
534554

535555
if (drvdata->quirks & QUIRK_NO_INIT_REPORTS)
@@ -553,13 +573,13 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
553573
goto err_stop_hw;
554574
}
555575

556-
if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
576+
if (drvdata->tp) {
557577
drvdata->input->name = "Asus TouchPad";
558578
} else {
559579
drvdata->input->name = "Asus Keyboard";
560580
}
561581

562-
if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
582+
if (drvdata->tp) {
563583
ret = asus_start_multitouch(hdev);
564584
if (ret)
565585
goto err_stop_hw;
@@ -606,7 +626,7 @@ static const struct hid_device_id asus_devices[] = {
606626
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
607627
USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD), I2C_KEYBOARD_QUIRKS},
608628
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
609-
USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD), TOUCHPAD_QUIRKS },
629+
USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD), I2C_TOUCHPAD_QUIRKS },
610630
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
611631
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) },
612632
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,

0 commit comments

Comments
 (0)