|
@@ -57,15 +57,18 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 };
|
|
|
static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
|
|
|
|
|
|
static void __wacom_notify_battery(struct wacom_battery *battery,
|
|
|
- int bat_capacity, bool bat_charging,
|
|
|
- bool bat_connected, bool ps_connected)
|
|
|
+ int bat_status, int bat_capacity,
|
|
|
+ bool bat_charging, bool bat_connected,
|
|
|
+ bool ps_connected)
|
|
|
{
|
|
|
- bool changed = battery->battery_capacity != bat_capacity ||
|
|
|
+ bool changed = battery->bat_status != bat_status ||
|
|
|
+ battery->battery_capacity != bat_capacity ||
|
|
|
battery->bat_charging != bat_charging ||
|
|
|
battery->bat_connected != bat_connected ||
|
|
|
battery->ps_connected != ps_connected;
|
|
|
|
|
|
if (changed) {
|
|
|
+ battery->bat_status = bat_status;
|
|
|
battery->battery_capacity = bat_capacity;
|
|
|
battery->bat_charging = bat_charging;
|
|
|
battery->bat_connected = bat_connected;
|
|
@@ -77,13 +80,13 @@ static void __wacom_notify_battery(struct wacom_battery *battery,
|
|
|
}
|
|
|
|
|
|
static void wacom_notify_battery(struct wacom_wac *wacom_wac,
|
|
|
- int bat_capacity, bool bat_charging, bool bat_connected,
|
|
|
- bool ps_connected)
|
|
|
+ int bat_status, int bat_capacity, bool bat_charging,
|
|
|
+ bool bat_connected, bool ps_connected)
|
|
|
{
|
|
|
struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
|
|
|
|
|
|
- __wacom_notify_battery(&wacom->battery, bat_capacity, bat_charging,
|
|
|
- bat_connected, ps_connected);
|
|
|
+ __wacom_notify_battery(&wacom->battery, bat_status, bat_capacity,
|
|
|
+ bat_charging, bat_connected, ps_connected);
|
|
|
}
|
|
|
|
|
|
static int wacom_penpartner_irq(struct wacom_wac *wacom)
|
|
@@ -448,8 +451,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
|
|
|
rw = (data[7] >> 2 & 0x07);
|
|
|
battery_capacity = batcap_gr[rw];
|
|
|
ps_connected = rw == 7;
|
|
|
- wacom_notify_battery(wacom, battery_capacity, ps_connected,
|
|
|
- 1, ps_connected);
|
|
|
+ wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,
|
|
|
+ battery_capacity, ps_connected, 1,
|
|
|
+ ps_connected);
|
|
|
}
|
|
|
exit:
|
|
|
return retval;
|
|
@@ -1071,7 +1075,8 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
|
|
|
wacom->led.groups[i].select = touch_ring_mode;
|
|
|
}
|
|
|
|
|
|
- __wacom_notify_battery(&remote->remotes[index].battery, bat_percent,
|
|
|
+ __wacom_notify_battery(&remote->remotes[index].battery,
|
|
|
+ WACOM_POWER_SUPPLY_STATUS_AUTO, bat_percent,
|
|
|
bat_charging, 1, bat_charging);
|
|
|
|
|
|
out:
|
|
@@ -1157,7 +1162,8 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
|
|
|
bat_charging = (power_raw & 0x08) ? 1 : 0;
|
|
|
ps_connected = (power_raw & 0x10) ? 1 : 0;
|
|
|
battery_capacity = batcap_i4[power_raw & 0x07];
|
|
|
- wacom_notify_battery(wacom, battery_capacity, bat_charging,
|
|
|
+ wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,
|
|
|
+ battery_capacity, bat_charging,
|
|
|
battery_capacity || bat_charging,
|
|
|
ps_connected);
|
|
|
break;
|
|
@@ -1334,7 +1340,8 @@ static void wacom_intuos_pro2_bt_battery(struct wacom_wac *wacom)
|
|
|
bool chg = data[284] & 0x80;
|
|
|
int battery_status = data[284] & 0x7F;
|
|
|
|
|
|
- wacom_notify_battery(wacom, battery_status, chg, 1, chg);
|
|
|
+ wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,
|
|
|
+ battery_status, chg, 1, chg);
|
|
|
}
|
|
|
|
|
|
static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len)
|
|
@@ -1696,20 +1703,92 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
|
|
|
+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;
|
|
|
- struct input_dev *input = wacom_wac->pad_input;
|
|
|
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;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,
|
|
|
+ struct hid_usage *usage, __s32 value)
|
|
|
+{
|
|
|
+ struct wacom *wacom = hid_get_drvdata(hdev);
|
|
|
+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
|
|
+ unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
|
|
|
+
|
|
|
+ switch (equivalent_usage) {
|
|
|
+ case HID_DG_BATTERYSTRENGTH:
|
|
|
+ if (value == 0) {
|
|
|
+ wacom_wac->hid_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ 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;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void wacom_wac_battery_pre_report(struct hid_device *hdev,
|
|
|
+ struct hid_report *report)
|
|
|
+{
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+static void wacom_wac_battery_report(struct hid_device *hdev,
|
|
|
+ struct hid_report *report)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+
|
|
|
+ wacom_notify_battery(wacom_wac, status, capacity, charging,
|
|
|
+ connected, powered);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void wacom_wac_pad_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;
|
|
|
+ struct input_dev *input = wacom_wac->pad_input;
|
|
|
+ unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
|
|
|
+
|
|
|
+ switch (equivalent_usage) {
|
|
|
case WACOM_HID_WD_ACCELEROMETER_X:
|
|
|
__set_bit(INPUT_PROP_ACCELEROMETER, input->propbit);
|
|
|
wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 0);
|
|
@@ -1803,27 +1882,6 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void wacom_wac_pad_battery_event(struct hid_device *hdev, struct hid_field *field,
|
|
|
- struct hid_usage *usage, __s32 value)
|
|
|
-{
|
|
|
- struct wacom *wacom = hid_get_drvdata(hdev);
|
|
|
- struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
|
|
- unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
|
|
|
-
|
|
|
- switch (equivalent_usage) {
|
|
|
- case WACOM_HID_WD_BATTERY_LEVEL:
|
|
|
- wacom_wac->hid_data.battery_capacity = value;
|
|
|
- wacom_wac->hid_data.bat_connected = 1;
|
|
|
- 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;
|
|
|
- break;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field,
|
|
|
struct hid_usage *usage, __s32 value)
|
|
|
{
|
|
@@ -1897,24 +1955,6 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev,
|
|
|
wacom_wac->hid_data.inrange_state = 0;
|
|
|
}
|
|
|
|
|
|
-static void wacom_wac_pad_battery_report(struct hid_device *hdev,
|
|
|
- struct hid_report *report)
|
|
|
-{
|
|
|
- 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 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, capacity, charging,
|
|
|
- connected, powered);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void wacom_wac_pad_report(struct hid_device *hdev,
|
|
|
struct hid_report *report)
|
|
|
{
|
|
@@ -1960,9 +2000,6 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
|
|
|
case HID_DG_INRANGE:
|
|
|
wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0);
|
|
|
break;
|
|
|
- case HID_DG_BATTERYSTRENGTH:
|
|
|
- features->quirks |= WACOM_QUIRK_BATTERY;
|
|
|
- break;
|
|
|
case HID_DG_INVERT:
|
|
|
wacom_map_usage(input, usage, field, EV_KEY,
|
|
|
BTN_TOOL_RUBBER, 0);
|
|
@@ -2035,10 +2072,6 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
|
|
|
if (!(features->quirks & WACOM_QUIRK_SENSE))
|
|
|
wacom_wac->hid_data.sense_state = value;
|
|
|
return;
|
|
|
- case HID_DG_BATTERYSTRENGTH:
|
|
|
- wacom_wac->hid_data.battery_capacity = value;
|
|
|
- wacom_wac->hid_data.bat_connected = 1;
|
|
|
- break;
|
|
|
case HID_DG_INVERT:
|
|
|
wacom_wac->hid_data.invert_state = value;
|
|
|
return;
|
|
@@ -2077,28 +2110,28 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
|
|
|
return;
|
|
|
case WACOM_HID_WD_OFFSETLEFT:
|
|
|
if (features->offset_left && value != features->offset_left)
|
|
|
- hid_warn(hdev, "%s: overriding exising left offset "
|
|
|
+ hid_warn(hdev, "%s: overriding existing left offset "
|
|
|
"%d -> %d\n", __func__, value,
|
|
|
features->offset_left);
|
|
|
features->offset_left = value;
|
|
|
return;
|
|
|
case WACOM_HID_WD_OFFSETRIGHT:
|
|
|
if (features->offset_right && value != features->offset_right)
|
|
|
- hid_warn(hdev, "%s: overriding exising right offset "
|
|
|
+ hid_warn(hdev, "%s: overriding existing right offset "
|
|
|
"%d -> %d\n", __func__, value,
|
|
|
features->offset_right);
|
|
|
features->offset_right = value;
|
|
|
return;
|
|
|
case WACOM_HID_WD_OFFSETTOP:
|
|
|
if (features->offset_top && value != features->offset_top)
|
|
|
- hid_warn(hdev, "%s: overriding exising top offset "
|
|
|
+ hid_warn(hdev, "%s: overriding existing top offset "
|
|
|
"%d -> %d\n", __func__, value,
|
|
|
features->offset_top);
|
|
|
features->offset_top = value;
|
|
|
return;
|
|
|
case WACOM_HID_WD_OFFSETBOTTOM:
|
|
|
if (features->offset_bottom && value != features->offset_bottom)
|
|
|
- hid_warn(hdev, "%s: overriding exising bottom offset "
|
|
|
+ hid_warn(hdev, "%s: overriding existing bottom offset "
|
|
|
"%d -> %d\n", __func__, value,
|
|
|
features->offset_bottom);
|
|
|
features->offset_bottom = value;
|
|
@@ -2395,7 +2428,10 @@ void wacom_wac_usage_mapping(struct hid_device *hdev,
|
|
|
if (WACOM_DIRECT_DEVICE(field))
|
|
|
features->device_type |= WACOM_DEVICETYPE_DIRECT;
|
|
|
|
|
|
- if (WACOM_PAD_FIELD(field))
|
|
|
+ /* usage tests must precede field tests */
|
|
|
+ if (WACOM_BATTERY_USAGE(usage))
|
|
|
+ wacom_wac_battery_usage_mapping(hdev, field, usage);
|
|
|
+ else if (WACOM_PAD_FIELD(field))
|
|
|
wacom_wac_pad_usage_mapping(hdev, field, usage);
|
|
|
else if (WACOM_PEN_FIELD(field))
|
|
|
wacom_wac_pen_usage_mapping(hdev, field, usage);
|
|
@@ -2414,11 +2450,12 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
|
|
|
if (value > field->logical_maximum || value < field->logical_minimum)
|
|
|
return;
|
|
|
|
|
|
- if (WACOM_PAD_FIELD(field)) {
|
|
|
- wacom_wac_pad_battery_event(hdev, field, usage, value);
|
|
|
- if (wacom->wacom_wac.pad_input)
|
|
|
- wacom_wac_pad_event(hdev, field, usage, value);
|
|
|
- } else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
|
|
+ /* usage tests must precede field tests */
|
|
|
+ if (WACOM_BATTERY_USAGE(usage))
|
|
|
+ wacom_wac_battery_event(hdev, field, usage, value);
|
|
|
+ else if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
|
|
|
+ wacom_wac_pad_event(hdev, field, usage, value);
|
|
|
+ else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
|
|
wacom_wac_pen_event(hdev, field, usage, value);
|
|
|
else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
|
|
|
wacom_wac_finger_event(hdev, field, usage, value);
|
|
@@ -2452,6 +2489,8 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
|
|
|
if (wacom_wac->features.type != HID_GENERIC)
|
|
|
return;
|
|
|
|
|
|
+ wacom_wac_battery_pre_report(hdev, report);
|
|
|
+
|
|
|
if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
|
|
|
wacom_wac_pad_pre_report(hdev, report);
|
|
|
else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
|
@@ -2471,11 +2510,11 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
|
|
|
if (report->type != HID_INPUT_REPORT)
|
|
|
return;
|
|
|
|
|
|
- if (WACOM_PAD_FIELD(field)) {
|
|
|
- wacom_wac_pad_battery_report(hdev, report);
|
|
|
- if (wacom->wacom_wac.pad_input)
|
|
|
- wacom_wac_pad_report(hdev, report);
|
|
|
- } else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
|
|
+ wacom_wac_battery_report(hdev, report);
|
|
|
+
|
|
|
+ if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
|
|
|
+ wacom_wac_pad_report(hdev, report);
|
|
|
+ else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
|
|
wacom_wac_pen_report(hdev, report);
|
|
|
else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
|
|
|
wacom_wac_finger_report(hdev, report);
|
|
@@ -2813,13 +2852,14 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
|
|
|
wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);
|
|
|
}
|
|
|
|
|
|
- wacom_notify_battery(wacom, battery, charging, 1, 0);
|
|
|
+ wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,
|
|
|
+ battery, charging, 1, 0);
|
|
|
|
|
|
} else if (wacom->pid != 0) {
|
|
|
/* disconnected while previously connected */
|
|
|
wacom->pid = 0;
|
|
|
wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);
|
|
|
- wacom_notify_battery(wacom, 0, 0, 0, 0);
|
|
|
+ wacom_notify_battery(wacom, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -2847,8 +2887,8 @@ 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);
|
|
|
|
|
|
- wacom_notify_battery(wacom_wac, battery, charging,
|
|
|
- battery || charging, 1);
|
|
|
+ wacom_notify_battery(wacom_wac, WACOM_POWER_SUPPLY_STATUS_AUTO,
|
|
|
+ battery, charging, battery || charging, 1);
|
|
|
|
|
|
if (!wacom->battery.battery &&
|
|
|
!(features->quirks & WACOM_QUIRK_BATTERY)) {
|
|
@@ -2860,7 +2900,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)
|
|
|
wacom->battery.battery) {
|
|
|
features->quirks &= ~WACOM_QUIRK_BATTERY;
|
|
|
wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
|
|
|
- wacom_notify_battery(wacom_wac, 0, 0, 0, 0);
|
|
|
+ wacom_notify_battery(wacom_wac, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|