Skip to content

Commit a9b50ea

Browse files
committed
Merge: Rebase Wacom to v6.15
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7133 This is an almost complete rebase to v6.15 for the wacom driver. Almost because one commit is left on the side: 88006b8 ("HID: wacom: Initialize brightness of LED trigger"). This one relies on a leds change not yet backported to RHEL 9. JIRA: https://issues.redhat.com/browse/RHEL-102058 Signed-off-by: Benjamin Tissoires <[email protected]> Approved-by: Bastien Nocera <[email protected]> Approved-by: Tony Camuso <[email protected]> Approved-by: CKI KWF Bot <[email protected]> Merged-by: Jarod Wilson <[email protected]>
2 parents 7528960 + 245cd1c commit a9b50ea

File tree

4 files changed

+154
-38
lines changed

4 files changed

+154
-38
lines changed

drivers/hid/wacom.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,14 @@ static inline __u32 wacom_s32tou(s32 value, __u8 n)
218218
return value & (1 << (n - 1)) ? value & (~(~0U << n)) : value;
219219
}
220220

221+
static inline u32 wacom_rescale(u32 value, u32 in_max, u32 out_max)
222+
{
223+
if (in_max == 0 || out_max == 0)
224+
return 0;
225+
value = clamp(value, 0, in_max);
226+
return DIV_ROUND_CLOSEST(value * out_max, in_max);
227+
}
228+
221229
extern const struct hid_device_id wacom_ids[];
222230

223231
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);

drivers/hid/wacom_sys.c

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,34 @@ static void wacom_wac_queue_flush(struct hid_device *hdev,
6969
struct kfifo_rec_ptr_2 *fifo)
7070
{
7171
while (!kfifo_is_empty(fifo)) {
72-
u8 buf[WACOM_PKGLEN_MAX];
73-
int size;
72+
int size = kfifo_peek_len(fifo);
73+
u8 *buf;
74+
unsigned int count;
7475
int err;
7576

76-
size = kfifo_out(fifo, buf, sizeof(buf));
77+
buf = kzalloc(size, GFP_KERNEL);
78+
if (!buf) {
79+
kfifo_skip(fifo);
80+
continue;
81+
}
82+
83+
count = kfifo_out(fifo, buf, size);
84+
if (count != size) {
85+
// Hard to say what is the "right" action in this
86+
// circumstance. Skipping the entry and continuing
87+
// to flush seems reasonable enough, however.
88+
hid_warn(hdev, "%s: removed fifo entry with unexpected size\n",
89+
__func__);
90+
kfree(buf);
91+
continue;
92+
}
7793
err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, false);
7894
if (err) {
7995
hid_warn(hdev, "%s: unable to flush event due to error %d\n",
8096
__func__, err);
8197
}
98+
99+
kfree(buf);
82100
}
83101
}
84102

@@ -158,13 +176,10 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
158176
if (wacom->wacom_wac.features.type == BOOTLOADER)
159177
return 0;
160178

161-
if (size > WACOM_PKGLEN_MAX)
162-
return 1;
163-
164179
if (wacom_wac_pen_serial_enforce(hdev, report, raw_data, size))
165180
return -1;
166181

167-
memcpy(wacom->wacom_wac.data, raw_data, size);
182+
wacom->wacom_wac.data = raw_data;
168183

169184
wacom_wac_irq(&wacom->wacom_wac, size);
170185

@@ -1084,6 +1099,17 @@ static ssize_t wacom_luminance_store(struct wacom *wacom, u8 *dest,
10841099
mutex_lock(&wacom->lock);
10851100

10861101
*dest = value & 0x7f;
1102+
for (unsigned int i = 0; i < wacom->led.count; i++) {
1103+
struct wacom_group_leds *group = &wacom->led.groups[i];
1104+
1105+
for (unsigned int j = 0; j < group->count; j++) {
1106+
if (dest == &wacom->led.llv)
1107+
group->leds[j].llv = *dest;
1108+
else if (dest == &wacom->led.hlv)
1109+
group->leds[j].hlv = *dest;
1110+
}
1111+
}
1112+
10871113
err = wacom_led_control(wacom);
10881114

10891115
mutex_unlock(&wacom->lock);
@@ -1275,6 +1301,7 @@ static void wacom_devm_kfifo_release(struct device *dev, void *res)
12751301
static int wacom_devm_kfifo_alloc(struct wacom *wacom)
12761302
{
12771303
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1304+
int fifo_size = min(PAGE_SIZE, 10 * wacom_wac->features.pktlen);
12781305
struct kfifo_rec_ptr_2 *pen_fifo;
12791306
int error;
12801307

@@ -1285,7 +1312,7 @@ static int wacom_devm_kfifo_alloc(struct wacom *wacom)
12851312
if (!pen_fifo)
12861313
return -ENOMEM;
12871314

1288-
error = kfifo_alloc(pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL);
1315+
error = kfifo_alloc(pen_fifo, fifo_size, GFP_KERNEL);
12891316
if (error) {
12901317
devres_free(pen_fifo);
12911318
return error;
@@ -1302,10 +1329,10 @@ enum led_brightness wacom_leds_brightness_get(struct wacom_led *led)
13021329
struct wacom *wacom = led->wacom;
13031330

13041331
if (wacom->led.max_hlv)
1305-
return led->hlv * LED_FULL / wacom->led.max_hlv;
1332+
return wacom_rescale(led->hlv, wacom->led.max_hlv, LED_FULL);
13061333

13071334
if (wacom->led.max_llv)
1308-
return led->llv * LED_FULL / wacom->led.max_llv;
1335+
return wacom_rescale(led->llv, wacom->led.max_llv, LED_FULL);
13091336

13101337
/* device doesn't support brightness tuning */
13111338
return LED_FULL;
@@ -1337,8 +1364,8 @@ static int wacom_led_brightness_set(struct led_classdev *cdev,
13371364
goto out;
13381365
}
13391366

1340-
led->llv = wacom->led.llv = wacom->led.max_llv * brightness / LED_FULL;
1341-
led->hlv = wacom->led.hlv = wacom->led.max_hlv * brightness / LED_FULL;
1367+
led->llv = wacom->led.llv = wacom_rescale(brightness, LED_FULL, wacom->led.max_llv);
1368+
led->hlv = wacom->led.hlv = wacom_rescale(brightness, LED_FULL, wacom->led.max_hlv);
13421369

13431370
wacom->led.groups[led->group].select = led->id;
13441371

@@ -2019,14 +2046,18 @@ static int wacom_initialize_remotes(struct wacom *wacom)
20192046

20202047
remote->remote_dir = kobject_create_and_add("wacom_remote",
20212048
&wacom->hdev->dev.kobj);
2022-
if (!remote->remote_dir)
2049+
if (!remote->remote_dir) {
2050+
kfifo_free(&remote->remote_fifo);
20232051
return -ENOMEM;
2052+
}
20242053

20252054
error = sysfs_create_files(remote->remote_dir, remote_unpair_attrs);
20262055

20272056
if (error) {
20282057
hid_err(wacom->hdev,
20292058
"cannot create sysfs group err: %d\n", error);
2059+
kfifo_free(&remote->remote_fifo);
2060+
kobject_put(remote->remote_dir);
20302061
return error;
20312062
}
20322063

@@ -2241,7 +2272,8 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix)
22412272
if (hid_is_usb(wacom->hdev)) {
22422273
struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent);
22432274
struct usb_device *dev = interface_to_usbdev(intf);
2244-
product_name = dev->product;
2275+
if (dev->product != NULL)
2276+
product_name = dev->product;
22452277
}
22462278

22472279
if (wacom->hdev->bus == BUS_I2C) {
@@ -2338,12 +2370,16 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
23382370
unsigned int connect_mask = HID_CONNECT_HIDRAW;
23392371

23402372
features->pktlen = wacom_compute_pktlen(hdev);
2341-
if (features->pktlen > WACOM_PKGLEN_MAX)
2342-
return -EINVAL;
2373+
if (!features->pktlen)
2374+
return -ENODEV;
23432375

23442376
if (!devres_open_group(&hdev->dev, wacom, GFP_KERNEL))
23452377
return -ENOMEM;
23462378

2379+
error = wacom_devm_kfifo_alloc(wacom);
2380+
if (error)
2381+
goto fail;
2382+
23472383
wacom->resources = true;
23482384

23492385
error = wacom_allocate_inputs(wacom);
@@ -2807,10 +2843,6 @@ static int wacom_probe(struct hid_device *hdev,
28072843
if (features->check_for_hid_type && features->hid_type != hdev->type)
28082844
return -ENODEV;
28092845

2810-
error = wacom_devm_kfifo_alloc(wacom);
2811-
if (error)
2812-
return error;
2813-
28142846
wacom_wac->hid_data.inputmode = -1;
28152847
wacom_wac->mode_report = -1;
28162848

@@ -2871,6 +2903,7 @@ static void wacom_remove(struct hid_device *hdev)
28712903
hid_hw_stop(hdev);
28722904

28732905
cancel_delayed_work_sync(&wacom->init_work);
2906+
cancel_delayed_work_sync(&wacom->aes_battery_work);
28742907
cancel_work_sync(&wacom->wireless_work);
28752908
cancel_work_sync(&wacom->battery_work);
28762909
cancel_work_sync(&wacom->remote_work);

drivers/hid/wacom_wac.c

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,12 +1201,10 @@ static void wacom_intuos_bt_process_data(struct wacom_wac *wacom,
12011201

12021202
static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
12031203
{
1204-
unsigned char data[WACOM_PKGLEN_MAX];
1204+
u8 *data = kmemdup(wacom->data, len, GFP_KERNEL);
12051205
int i = 1;
12061206
unsigned power_raw, battery_capacity, bat_charging, ps_connected;
12071207

1208-
memcpy(data, wacom->data, len);
1209-
12101208
switch (data[0]) {
12111209
case 0x04:
12121210
wacom_intuos_bt_process_data(wacom, data + i);
@@ -1230,8 +1228,10 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
12301228
dev_dbg(wacom->pen_input->dev.parent,
12311229
"Unknown report: %d,%d size:%zu\n",
12321230
data[0], data[1], len);
1233-
return 0;
1231+
break;
12341232
}
1233+
1234+
kfree(data);
12351235
return 0;
12361236
}
12371237

@@ -1353,9 +1353,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
13531353
rotation -= 1800;
13541354

13551355
input_report_abs(pen_input, ABS_TILT_X,
1356-
(char)frame[7]);
1356+
(signed char)frame[7]);
13571357
input_report_abs(pen_input, ABS_TILT_Y,
1358-
(char)frame[8]);
1358+
(signed char)frame[8]);
13591359
input_report_abs(pen_input, ABS_Z, rotation);
13601360
input_report_abs(pen_input, ABS_WHEEL,
13611361
get_unaligned_le16(&frame[11]));
@@ -1906,11 +1906,12 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
19061906
if ((code == ABS_X || code == ABS_Y) && !resolution) {
19071907
resolution = WACOM_INTUOS_RES;
19081908
hid_warn(input,
1909-
"Wacom usage (%d) missing resolution \n",
1910-
code);
1909+
"Using default resolution for axis type 0x%x code 0x%x\n",
1910+
type, code);
19111911
}
19121912
input_abs_set_res(input, code, resolution);
19131913
break;
1914+
case EV_REL:
19141915
case EV_KEY:
19151916
case EV_MSC:
19161917
case EV_SW:
@@ -2047,7 +2048,23 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
20472048
features->device_type |= WACOM_DEVICETYPE_PAD;
20482049
break;
20492050
case WACOM_HID_WD_TOUCHRING:
2050-
wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
2051+
if (field->flags & HID_MAIN_ITEM_RELATIVE) {
2052+
wacom_wac->relring_count++;
2053+
if (wacom_wac->relring_count == 1) {
2054+
wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL_HI_RES, 0);
2055+
set_bit(REL_WHEEL, input->relbit);
2056+
}
2057+
else if (wacom_wac->relring_count == 2) {
2058+
wacom_map_usage(input, usage, field, EV_REL, REL_HWHEEL_HI_RES, 0);
2059+
set_bit(REL_HWHEEL, input->relbit);
2060+
}
2061+
} else {
2062+
wacom_wac->absring_count++;
2063+
if (wacom_wac->absring_count == 1)
2064+
wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
2065+
else if (wacom_wac->absring_count == 2)
2066+
wacom_map_usage(input, usage, field, EV_ABS, ABS_THROTTLE, 0);
2067+
}
20512068
features->device_type |= WACOM_DEVICETYPE_PAD;
20522069
break;
20532070
case WACOM_HID_WD_TOUCHRINGSTATUS:
@@ -2112,7 +2129,10 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
21122129
return;
21132130

21142131
if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) {
2115-
if (usage->hid != WACOM_HID_WD_TOUCHRING)
2132+
bool is_abs_touchring = usage->hid == WACOM_HID_WD_TOUCHRING &&
2133+
!(field->flags & HID_MAIN_ITEM_RELATIVE);
2134+
2135+
if (!is_abs_touchring)
21162136
wacom_wac->hid_data.inrange_state |= value;
21172137
}
21182138

@@ -2165,6 +2185,52 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
21652185
hdev->product == 0x3AA)
21662186
value = wacom_offset_rotation(input, usage, value, 1, 2);
21672187
}
2188+
else if (field->flags & HID_MAIN_ITEM_RELATIVE) {
2189+
int hires_value = value * 120 / usage->resolution_multiplier;
2190+
int *ring_value;
2191+
int lowres_code;
2192+
2193+
if (usage->code == REL_WHEEL_HI_RES) {
2194+
/* We must invert the sign for vertical
2195+
* relative scrolling. Clockwise
2196+
* rotation produces positive values
2197+
* from HW, but userspace treats
2198+
* positive REL_WHEEL as a scroll *up*!
2199+
*/
2200+
hires_value = -hires_value;
2201+
ring_value = &wacom_wac->hid_data.ring_value;
2202+
lowres_code = REL_WHEEL;
2203+
}
2204+
else if (usage->code == REL_HWHEEL_HI_RES) {
2205+
/* No need to invert the sign for
2206+
* horizontal relative scrolling.
2207+
* Clockwise rotation produces positive
2208+
* values from HW and userspace treats
2209+
* positive REL_HWHEEL as a scroll
2210+
* right.
2211+
*/
2212+
ring_value = &wacom_wac->hid_data.ring2_value;
2213+
lowres_code = REL_HWHEEL;
2214+
}
2215+
else {
2216+
hid_err(wacom->hdev, "unrecognized relative wheel with code %d\n",
2217+
usage->code);
2218+
break;
2219+
}
2220+
2221+
value = hires_value;
2222+
*ring_value += hires_value;
2223+
2224+
/* Emulate a legacy wheel click for every 120
2225+
* units of hi-res travel.
2226+
*/
2227+
if (*ring_value >= 120 || *ring_value <= -120) {
2228+
int clicks = *ring_value / 120;
2229+
2230+
input_event(input, usage->type, lowres_code, clicks);
2231+
*ring_value -= clicks * 120;
2232+
}
2233+
}
21682234
else {
21692235
value = wacom_offset_rotation(input, usage, value, 1, 4);
21702236
}
@@ -2356,9 +2422,11 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
23562422
wacom_wac->hid_data.sense_state = value;
23572423
return;
23582424
case HID_DG_INVERT:
2359-
wacom_wac->hid_data.invert_state = value;
2425+
wacom_wac->hid_data.eraser |= value;
23602426
return;
23612427
case HID_DG_ERASER:
2428+
wacom_wac->hid_data.eraser |= value;
2429+
fallthrough;
23622430
case HID_DG_TIPSWITCH:
23632431
wacom_wac->hid_data.tipswitch |= value;
23642432
return;
@@ -2499,7 +2567,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
24992567

25002568
if (entering_range) { /* first in range */
25012569
/* Going into range select tool */
2502-
if (wacom_wac->hid_data.invert_state)
2570+
if (wacom_wac->hid_data.eraser)
25032571
wacom_wac->tool[0] = BTN_TOOL_RUBBER;
25042572
else if (wacom_wac->features.quirks & WACOM_QUIRK_AESPEN)
25052573
wacom_wac->tool[0] = BTN_TOOL_PEN;
@@ -2553,6 +2621,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
25532621
}
25542622

25552623
wacom_wac->hid_data.tipswitch = false;
2624+
wacom_wac->hid_data.eraser = false;
25562625

25572626
input_sync(input);
25582627
}
@@ -4877,6 +4946,10 @@ static const struct wacom_features wacom_features_0x94 =
48774946
HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
48784947
.driver_data = (kernel_ulong_t)&wacom_features_##prod
48794948

4949+
#define PCI_DEVICE_WACOM(prod) \
4950+
HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
4951+
.driver_data = (kernel_ulong_t)&wacom_features_##prod
4952+
48804953
#define USB_DEVICE_LENOVO(prod) \
48814954
HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \
48824955
.driver_data = (kernel_ulong_t)&wacom_features_##prod
@@ -5046,6 +5119,7 @@ const struct hid_device_id wacom_ids[] = {
50465119

50475120
{ USB_DEVICE_WACOM(HID_ANY_ID) },
50485121
{ I2C_DEVICE_WACOM(HID_ANY_ID) },
5122+
{ PCI_DEVICE_WACOM(HID_ANY_ID) },
50495123
{ BT_DEVICE_WACOM(HID_ANY_ID) },
50505124
{ }
50515125
};

0 commit comments

Comments
 (0)