Skip to content

Commit

Permalink
Merge branch 'for-6.4/wacom' into for-linus
Browse files Browse the repository at this point in the history
- improved handling of battery quirk (Jason Gerecke)
- lazy initialization of battery interfaces (Jason Gerecke)
  • Loading branch information
Jiri Kosina committed Apr 26, 2023
2 parents ab396fb + bea407a commit c3a6ef3
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 41 deletions.
10 changes: 0 additions & 10 deletions drivers/hid/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -2372,13 +2372,6 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
if (error)
goto fail;

if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) &&
(features->quirks & WACOM_QUIRK_BATTERY)) {
error = wacom_initialize_battery(wacom);
if (error)
goto fail;
}

error = wacom_register_inputs(wacom);
if (error)
goto fail;
Expand Down Expand Up @@ -2509,9 +2502,6 @@ static void wacom_wireless_work(struct work_struct *work)

strscpy(wacom_wac->name, wacom_wac1->name,
sizeof(wacom_wac->name));
error = wacom_initialize_battery(wacom);
if (error)
goto fail;
}

return;
Expand Down
84 changes: 53 additions & 31 deletions drivers/hid/wacom_wac.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ static void wacom_notify_battery(struct wacom_wac *wacom_wac,
bool bat_connected, bool ps_connected)
{
struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
bool bat_initialized = wacom->battery.battery;
bool has_quirk = wacom_wac->features.quirks & WACOM_QUIRK_BATTERY;

if (bat_initialized != has_quirk)
wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);

__wacom_notify_battery(&wacom->battery, bat_status, bat_capacity,
bat_charging, bat_connected, ps_connected);
Expand Down Expand Up @@ -1308,6 +1313,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)

struct input_dev *pen_input = wacom->pen_input;
unsigned char *data = wacom->data;
int number_of_valid_frames = 0;
int time_interval = 15000000;
ktime_t time_packet_received = ktime_get();
int i;

if (wacom->features.type == INTUOSP2_BT ||
Expand All @@ -1328,12 +1336,30 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF;
}

/* number of valid frames */
for (i = 0; i < pen_frames; i++) {
unsigned char *frame = &data[i*pen_frame_len + 1];
bool valid = frame[0] & 0x80;

if (valid)
number_of_valid_frames++;
}

if (number_of_valid_frames) {
if (wacom->hid_data.time_delayed)
time_interval = ktime_get() - wacom->hid_data.time_delayed;
time_interval /= number_of_valid_frames;
wacom->hid_data.time_delayed = time_packet_received;
}

for (i = 0; i < number_of_valid_frames; i++) {
unsigned char *frame = &data[i*pen_frame_len + 1];
bool valid = frame[0] & 0x80;
bool prox = frame[0] & 0x40;
bool range = frame[0] & 0x20;
bool invert = frame[0] & 0x10;
int frames_number_reversed = number_of_valid_frames - i - 1;
int event_timestamp = time_packet_received - frames_number_reversed * time_interval;

if (!valid)
continue;
Expand All @@ -1346,6 +1372,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
wacom->tool[0] = 0;
wacom->id[0] = 0;
wacom->serial[0] = 0;
wacom->hid_data.time_delayed = 0;
return;
}

Expand Down Expand Up @@ -1382,6 +1409,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
get_unaligned_le16(&frame[11]));
}
}

if (wacom->tool[0]) {
input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
if (wacom->features.type == INTUOSP2_BT ||
Expand All @@ -1405,6 +1433,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)

wacom->shared->stylus_in_proximity = prox;

/* add timestamp to unpack the frames */
input_set_timestamp(pen_input, event_timestamp);

input_sync(pen_input);
}
}
Expand Down Expand Up @@ -1895,6 +1926,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
int fmax = field->logical_maximum;
unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
int resolution_code = code;
int resolution = hidinput_calc_abs_res(field, resolution_code);

if (equivalent_usage == HID_DG_TWIST) {
resolution_code = ABS_RZ;
Expand All @@ -1915,8 +1947,15 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
switch (type) {
case EV_ABS:
input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
input_abs_set_res(input, code,
hidinput_calc_abs_res(field, resolution_code));

/* older tablet may miss physical usage */
if ((code == ABS_X || code == ABS_Y) && !resolution) {
resolution = WACOM_INTUOS_RES;
hid_warn(input,
"Wacom usage (%d) missing resolution \n",
code);
}
input_abs_set_res(input, code, resolution);
break;
case EV_KEY:
case EV_MSC:
Expand All @@ -1929,18 +1968,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
static void wacom_wac_battery_usage_mapping(struct hid_device *hdev,
struct hid_field *field, struct hid_usage *usage)
{
struct wacom *wacom = hid_get_drvdata(hdev);
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
struct wacom_features *features = &wacom_wac->features;
unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);

switch (equivalent_usage) {
case HID_DG_BATTERYSTRENGTH:
case WACOM_HID_WD_BATTERY_LEVEL:
case WACOM_HID_WD_BATTERY_CHARGING:
features->quirks |= WACOM_QUIRK_BATTERY;
break;
}
return;
}

static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,
Expand All @@ -1961,18 +1989,21 @@ static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *f
wacom_wac->hid_data.bat_connected = 1;
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
}
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
break;
case WACOM_HID_WD_BATTERY_LEVEL:
value = value * 100 / (field->logical_maximum - field->logical_minimum);
wacom_wac->hid_data.battery_capacity = value;
wacom_wac->hid_data.bat_connected = 1;
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
break;
case WACOM_HID_WD_BATTERY_CHARGING:
wacom_wac->hid_data.bat_charging = value;
wacom_wac->hid_data.ps_connected = value;
wacom_wac->hid_data.bat_connected = 1;
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
break;
}
}
Expand All @@ -1988,18 +2019,15 @@ static void wacom_wac_battery_report(struct hid_device *hdev,
{
struct wacom *wacom = hid_get_drvdata(hdev);
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
struct wacom_features *features = &wacom_wac->features;

if (features->quirks & WACOM_QUIRK_BATTERY) {
int status = wacom_wac->hid_data.bat_status;
int capacity = wacom_wac->hid_data.battery_capacity;
bool charging = wacom_wac->hid_data.bat_charging;
bool connected = wacom_wac->hid_data.bat_connected;
bool powered = wacom_wac->hid_data.ps_connected;
int status = wacom_wac->hid_data.bat_status;
int capacity = wacom_wac->hid_data.battery_capacity;
bool charging = wacom_wac->hid_data.bat_charging;
bool connected = wacom_wac->hid_data.bat_connected;
bool powered = wacom_wac->hid_data.ps_connected;

wacom_notify_battery(wacom_wac, status, capacity, charging,
connected, powered);
}
wacom_notify_battery(wacom_wac, status, capacity, charging,
connected, powered);
}

static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
Expand Down Expand Up @@ -3365,19 +3393,13 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)
int battery = (data[8] & 0x3f) * 100 / 31;
bool charging = !!(data[8] & 0x80);

features->quirks |= WACOM_QUIRK_BATTERY;
wacom_notify_battery(wacom_wac, WACOM_POWER_SUPPLY_STATUS_AUTO,
battery, charging, battery || charging, 1);

if (!wacom->battery.battery &&
!(features->quirks & WACOM_QUIRK_BATTERY)) {
features->quirks |= WACOM_QUIRK_BATTERY;
wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
}
}
else if ((features->quirks & WACOM_QUIRK_BATTERY) &&
wacom->battery.battery) {
features->quirks &= ~WACOM_QUIRK_BATTERY;
wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
wacom_notify_battery(wacom_wac, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0);
}
return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/wacom_wac.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ struct hid_data {
int ps_connected;
bool pad_input_event_flag;
unsigned short sequence_number;
int time_delayed;
};

struct wacom_remote_data {
Expand Down

0 comments on commit c3a6ef3

Please sign in to comment.