|
@@ -45,6 +45,27 @@ 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 unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
|
|
|
|
|
|
|
|
+static void wacom_notify_battery(struct wacom_wac *wacom_wac,
|
|
|
|
+ int bat_capacity, bool bat_charging, bool bat_connected,
|
|
|
|
+ bool ps_connected)
|
|
|
|
+{
|
|
|
|
+ struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
|
|
|
|
+ bool changed = wacom_wac->battery_capacity != bat_capacity ||
|
|
|
|
+ wacom_wac->bat_charging != bat_charging ||
|
|
|
|
+ wacom_wac->bat_connected != bat_connected ||
|
|
|
|
+ wacom_wac->ps_connected != ps_connected;
|
|
|
|
+
|
|
|
|
+ if (changed) {
|
|
|
|
+ wacom_wac->battery_capacity = bat_capacity;
|
|
|
|
+ wacom_wac->bat_charging = bat_charging;
|
|
|
|
+ wacom_wac->bat_connected = bat_connected;
|
|
|
|
+ wacom_wac->ps_connected = ps_connected;
|
|
|
|
+
|
|
|
|
+ if (wacom->battery)
|
|
|
|
+ power_supply_changed(wacom->battery);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static int wacom_penpartner_irq(struct wacom_wac *wacom)
|
|
static int wacom_penpartner_irq(struct wacom_wac *wacom)
|
|
{
|
|
{
|
|
unsigned char *data = wacom->data;
|
|
unsigned char *data = wacom->data;
|
|
@@ -419,17 +440,26 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
|
|
rw = (data[7] >> 2 & 0x07);
|
|
rw = (data[7] >> 2 & 0x07);
|
|
battery_capacity = batcap_gr[rw];
|
|
battery_capacity = batcap_gr[rw];
|
|
ps_connected = rw == 7;
|
|
ps_connected = rw == 7;
|
|
- if ((wacom->battery_capacity != battery_capacity) ||
|
|
|
|
- (wacom->ps_connected != ps_connected)) {
|
|
|
|
- wacom->battery_capacity = battery_capacity;
|
|
|
|
- wacom->ps_connected = ps_connected;
|
|
|
|
- wacom_notify_battery(wacom);
|
|
|
|
- }
|
|
|
|
|
|
+ wacom_notify_battery(wacom, battery_capacity, ps_connected,
|
|
|
|
+ 1, ps_connected);
|
|
}
|
|
}
|
|
exit:
|
|
exit:
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac)
|
|
|
|
+{
|
|
|
|
+ struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
|
|
|
|
+ struct hid_report *r;
|
|
|
|
+ struct hid_report_enum *re;
|
|
|
|
+
|
|
|
|
+ re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]);
|
|
|
|
+ r = re->report_id_hash[WACOM_REPORT_INTUOSREAD];
|
|
|
|
+ if (r) {
|
|
|
|
+ hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|
static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|
{
|
|
{
|
|
struct wacom_features *features = &wacom->features;
|
|
struct wacom_features *features = &wacom->features;
|
|
@@ -551,12 +581,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|
(features->type == CINTIQ && !(data[1] & 0x40)))
|
|
(features->type == CINTIQ && !(data[1] & 0x40)))
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
- if (wacom->shared) {
|
|
|
|
- wacom->shared->stylus_in_proximity = true;
|
|
|
|
-
|
|
|
|
- if (wacom->shared->touch_down)
|
|
|
|
- return 1;
|
|
|
|
- }
|
|
|
|
|
|
+ wacom->shared->stylus_in_proximity = true;
|
|
|
|
+ if (wacom->shared->touch_down)
|
|
|
|
+ return 1;
|
|
|
|
|
|
/* in Range while exiting */
|
|
/* in Range while exiting */
|
|
if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) {
|
|
if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) {
|
|
@@ -568,8 +595,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|
|
|
|
|
/* Exit report */
|
|
/* Exit report */
|
|
if ((data[1] & 0xfe) == 0x80) {
|
|
if ((data[1] & 0xfe) == 0x80) {
|
|
- if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
|
|
|
|
- wacom->shared->stylus_in_proximity = false;
|
|
|
|
|
|
+ wacom->shared->stylus_in_proximity = false;
|
|
wacom->reporting_data = false;
|
|
wacom->reporting_data = false;
|
|
|
|
|
|
/* don't report exit if we don't know the ID */
|
|
/* don't report exit if we don't know the ID */
|
|
@@ -610,8 +636,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|
}
|
|
}
|
|
|
|
|
|
/* don't report other events if we don't know the ID */
|
|
/* don't report other events if we don't know the ID */
|
|
- if (!wacom->id[idx])
|
|
|
|
|
|
+ if (!wacom->id[idx]) {
|
|
|
|
+ /* but reschedule a read of the current tool */
|
|
|
|
+ wacom_intuos_schedule_prox_event(wacom);
|
|
return 1;
|
|
return 1;
|
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1023,15 +1052,9 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
|
|
bat_charging = (power_raw & 0x08) ? 1 : 0;
|
|
bat_charging = (power_raw & 0x08) ? 1 : 0;
|
|
ps_connected = (power_raw & 0x10) ? 1 : 0;
|
|
ps_connected = (power_raw & 0x10) ? 1 : 0;
|
|
battery_capacity = batcap_i4[power_raw & 0x07];
|
|
battery_capacity = batcap_i4[power_raw & 0x07];
|
|
- if ((wacom->battery_capacity != battery_capacity) ||
|
|
|
|
- (wacom->bat_charging != bat_charging) ||
|
|
|
|
- (wacom->ps_connected != ps_connected)) {
|
|
|
|
- wacom->battery_capacity = battery_capacity;
|
|
|
|
- wacom->bat_charging = bat_charging;
|
|
|
|
- wacom->ps_connected = ps_connected;
|
|
|
|
- wacom_notify_battery(wacom);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ wacom_notify_battery(wacom, battery_capacity, bat_charging,
|
|
|
|
+ battery_capacity || bat_charging,
|
|
|
|
+ ps_connected);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
dev_dbg(wacom->input->dev.parent,
|
|
dev_dbg(wacom->input->dev.parent,
|
|
@@ -1042,6 +1065,28 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
|
|
|
|
+{
|
|
|
|
+ struct input_dev *input = wacom->input;
|
|
|
|
+ unsigned touch_max = wacom->features.touch_max;
|
|
|
|
+ int count = 0;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ /* non-HID_GENERIC single touch input doesn't call this routine */
|
|
|
|
+ if ((touch_max == 1) && (wacom->features.type == HID_GENERIC))
|
|
|
|
+ return wacom->hid_data.tipswitch &&
|
|
|
|
+ !wacom->shared->stylus_in_proximity;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < input->mt->num_slots; i++) {
|
|
|
|
+ struct input_mt_slot *ps = &input->mt->slots[i];
|
|
|
|
+ int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
|
|
|
|
+ if (id >= 0)
|
|
|
|
+ count++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return count;
|
|
|
|
+}
|
|
|
|
+
|
|
static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
{
|
|
{
|
|
struct input_dev *input = wacom->input;
|
|
struct input_dev *input = wacom->input;
|
|
@@ -1052,7 +1097,6 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
int num_contacts_left = 4; /* maximum contacts per packet */
|
|
int num_contacts_left = 4; /* maximum contacts per packet */
|
|
int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
|
|
int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
|
|
int y_offset = 2;
|
|
int y_offset = 2;
|
|
- static int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
|
|
if (wacom->features.type == WACOM_27QHDT) {
|
|
if (wacom->features.type == WACOM_27QHDT) {
|
|
current_num_contacts = data[63];
|
|
current_num_contacts = data[63];
|
|
@@ -1065,10 +1109,8 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
* First packet resets the counter since only the first
|
|
* First packet resets the counter since only the first
|
|
* packet in series will have non-zero current_num_contacts.
|
|
* packet in series will have non-zero current_num_contacts.
|
|
*/
|
|
*/
|
|
- if (current_num_contacts) {
|
|
|
|
|
|
+ if (current_num_contacts)
|
|
wacom->num_contacts_left = current_num_contacts;
|
|
wacom->num_contacts_left = current_num_contacts;
|
|
- contact_with_no_pen_down_count = 0;
|
|
|
|
- }
|
|
|
|
|
|
|
|
contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
|
|
contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
|
|
|
|
|
|
@@ -1101,15 +1143,14 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
|
|
input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
|
|
input_report_abs(input, ABS_MT_ORIENTATION, w > h);
|
|
input_report_abs(input, ABS_MT_ORIENTATION, w > h);
|
|
}
|
|
}
|
|
- contact_with_no_pen_down_count++;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- input_mt_report_pointer_emulation(input, true);
|
|
|
|
|
|
+ input_mt_sync_frame(input);
|
|
|
|
|
|
wacom->num_contacts_left -= contacts_to_send;
|
|
wacom->num_contacts_left -= contacts_to_send;
|
|
if (wacom->num_contacts_left <= 0) {
|
|
if (wacom->num_contacts_left <= 0) {
|
|
wacom->num_contacts_left = 0;
|
|
wacom->num_contacts_left = 0;
|
|
- wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
|
|
|
+ wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
|
|
}
|
|
}
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -1122,7 +1163,6 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|
int current_num_contacts = data[2];
|
|
int current_num_contacts = data[2];
|
|
int contacts_to_send = 0;
|
|
int contacts_to_send = 0;
|
|
int x_offset = 0;
|
|
int x_offset = 0;
|
|
- static int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
|
|
/* MTTPC does not support Height and Width */
|
|
/* MTTPC does not support Height and Width */
|
|
if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)
|
|
if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)
|
|
@@ -1132,10 +1172,8 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|
* First packet resets the counter since only the first
|
|
* First packet resets the counter since only the first
|
|
* packet in series will have non-zero current_num_contacts.
|
|
* packet in series will have non-zero current_num_contacts.
|
|
*/
|
|
*/
|
|
- if (current_num_contacts) {
|
|
|
|
|
|
+ if (current_num_contacts)
|
|
wacom->num_contacts_left = current_num_contacts;
|
|
wacom->num_contacts_left = current_num_contacts;
|
|
- contact_with_no_pen_down_count = 0;
|
|
|
|
- }
|
|
|
|
|
|
|
|
/* There are at most 5 contacts per packet */
|
|
/* There are at most 5 contacts per packet */
|
|
contacts_to_send = min(5, wacom->num_contacts_left);
|
|
contacts_to_send = min(5, wacom->num_contacts_left);
|
|
@@ -1156,15 +1194,14 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|
int y = get_unaligned_le16(&data[offset + x_offset + 9]);
|
|
int y = get_unaligned_le16(&data[offset + x_offset + 9]);
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
- contact_with_no_pen_down_count++;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- input_mt_report_pointer_emulation(input, true);
|
|
|
|
|
|
+ input_mt_sync_frame(input);
|
|
|
|
|
|
wacom->num_contacts_left -= contacts_to_send;
|
|
wacom->num_contacts_left -= contacts_to_send;
|
|
if (wacom->num_contacts_left <= 0) {
|
|
if (wacom->num_contacts_left <= 0) {
|
|
wacom->num_contacts_left = 0;
|
|
wacom->num_contacts_left = 0;
|
|
- wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
|
|
|
+ wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
|
|
}
|
|
}
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -1173,7 +1210,6 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
|
|
{
|
|
{
|
|
struct input_dev *input = wacom->input;
|
|
struct input_dev *input = wacom->input;
|
|
unsigned char *data = wacom->data;
|
|
unsigned char *data = wacom->data;
|
|
- int contact_with_no_pen_down_count = 0;
|
|
|
|
int i;
|
|
int i;
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
for (i = 0; i < 2; i++) {
|
|
@@ -1188,13 +1224,12 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
|
|
|
|
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
- contact_with_no_pen_down_count++;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- input_mt_report_pointer_emulation(input, true);
|
|
|
|
|
|
+ input_mt_sync_frame(input);
|
|
|
|
|
|
/* keep touch state for pen event */
|
|
/* keep touch state for pen event */
|
|
- wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
|
|
|
+ wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -1522,29 +1557,6 @@ static int wacom_wac_finger_event(struct hid_device *hdev,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int wacom_wac_finger_count_touches(struct hid_device *hdev)
|
|
|
|
-{
|
|
|
|
- struct wacom *wacom = hid_get_drvdata(hdev);
|
|
|
|
- struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
|
|
|
- struct input_dev *input = wacom_wac->input;
|
|
|
|
- unsigned touch_max = wacom_wac->features.touch_max;
|
|
|
|
- int count = 0;
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- if (touch_max == 1)
|
|
|
|
- return wacom_wac->hid_data.tipswitch &&
|
|
|
|
- !wacom_wac->shared->stylus_in_proximity;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < input->mt->num_slots; i++) {
|
|
|
|
- struct input_mt_slot *ps = &input->mt->slots[i];
|
|
|
|
- int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
|
|
|
|
- if (id >= 0)
|
|
|
|
- count++;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return count;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void wacom_wac_finger_report(struct hid_device *hdev,
|
|
static void wacom_wac_finger_report(struct hid_device *hdev,
|
|
struct hid_report *report)
|
|
struct hid_report *report)
|
|
{
|
|
{
|
|
@@ -1559,7 +1571,7 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
|
|
input_sync(input);
|
|
input_sync(input);
|
|
|
|
|
|
/* keep touch state for pen event */
|
|
/* keep touch state for pen event */
|
|
- wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev);
|
|
|
|
|
|
+ wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
|
|
}
|
|
}
|
|
|
|
|
|
void wacom_wac_usage_mapping(struct hid_device *hdev,
|
|
void wacom_wac_usage_mapping(struct hid_device *hdev,
|
|
@@ -1619,7 +1631,6 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
|
|
struct input_dev *pad_input = wacom->pad_input;
|
|
struct input_dev *pad_input = wacom->pad_input;
|
|
unsigned char *data = wacom->data;
|
|
unsigned char *data = wacom->data;
|
|
int i;
|
|
int i;
|
|
- int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
|
|
if (data[0] != 0x02)
|
|
if (data[0] != 0x02)
|
|
return 0;
|
|
return 0;
|
|
@@ -1647,22 +1658,21 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
|
|
}
|
|
}
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
- contact_with_no_pen_down_count++;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- input_mt_report_pointer_emulation(input, true);
|
|
|
|
|
|
+ input_mt_sync_frame(input);
|
|
|
|
|
|
input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0);
|
|
input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0);
|
|
input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
|
|
input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
|
|
input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
|
|
input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
|
|
input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
|
|
input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
|
|
- wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
|
|
|
+ wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, int last_touch_count)
|
|
|
|
|
|
+static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
{
|
|
{
|
|
struct wacom_features *features = &wacom->features;
|
|
struct wacom_features *features = &wacom->features;
|
|
struct input_dev *input = wacom->input;
|
|
struct input_dev *input = wacom->input;
|
|
@@ -1670,7 +1680,7 @@ static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, in
|
|
int slot = input_mt_get_slot_by_key(input, data[0]);
|
|
int slot = input_mt_get_slot_by_key(input, data[0]);
|
|
|
|
|
|
if (slot < 0)
|
|
if (slot < 0)
|
|
- return 0;
|
|
|
|
|
|
+ return;
|
|
|
|
|
|
touch = touch && !wacom->shared->stylus_in_proximity;
|
|
touch = touch && !wacom->shared->stylus_in_proximity;
|
|
|
|
|
|
@@ -1702,9 +1712,7 @@ static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, in
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
|
|
input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
|
|
input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
|
|
input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
|
|
- last_touch_count++;
|
|
|
|
}
|
|
}
|
|
- return last_touch_count;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
@@ -1729,7 +1737,6 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
|
|
unsigned char *data = wacom->data;
|
|
unsigned char *data = wacom->data;
|
|
int count = data[1] & 0x07;
|
|
int count = data[1] & 0x07;
|
|
int i;
|
|
int i;
|
|
- int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
|
|
if (data[0] != 0x02)
|
|
if (data[0] != 0x02)
|
|
return 0;
|
|
return 0;
|
|
@@ -1740,15 +1747,13 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
|
|
int msg_id = data[offset];
|
|
int msg_id = data[offset];
|
|
|
|
|
|
if (msg_id >= 2 && msg_id <= 17)
|
|
if (msg_id >= 2 && msg_id <= 17)
|
|
- contact_with_no_pen_down_count =
|
|
|
|
- wacom_bpt3_touch_msg(wacom, data + offset,
|
|
|
|
- contact_with_no_pen_down_count);
|
|
|
|
|
|
+ wacom_bpt3_touch_msg(wacom, data + offset);
|
|
else if (msg_id == 128)
|
|
else if (msg_id == 128)
|
|
wacom_bpt3_button_msg(wacom, data + offset);
|
|
wacom_bpt3_button_msg(wacom, data + offset);
|
|
|
|
|
|
}
|
|
}
|
|
- input_mt_report_pointer_emulation(input, true);
|
|
|
|
- wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
|
|
|
+ input_mt_sync_frame(input);
|
|
|
|
+ wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -1760,23 +1765,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
|
|
unsigned char *data = wacom->data;
|
|
unsigned char *data = wacom->data;
|
|
int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
|
|
int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
|
|
|
|
|
|
- if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB)
|
|
|
|
|
|
+ if (data[0] != WACOM_REPORT_PENABLED)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
- if (data[0] == WACOM_REPORT_USB) {
|
|
|
|
- if (features->type == INTUOSHT &&
|
|
|
|
- wacom->shared->touch_input &&
|
|
|
|
- features->touch_max) {
|
|
|
|
- input_report_switch(wacom->shared->touch_input,
|
|
|
|
- SW_MUTE_DEVICE, data[8] & 0x40);
|
|
|
|
- input_sync(wacom->shared->touch_input);
|
|
|
|
- }
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (wacom->shared->touch_down)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
prox = (data[1] & 0x20) == 0x20;
|
|
prox = (data[1] & 0x20) == 0x20;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1789,17 +1780,21 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
|
|
*
|
|
*
|
|
* Hardware does report zero in most out-of-prox cases but not all.
|
|
* Hardware does report zero in most out-of-prox cases but not all.
|
|
*/
|
|
*/
|
|
- if (prox) {
|
|
|
|
- if (!wacom->shared->stylus_in_proximity) {
|
|
|
|
- if (data[1] & 0x08) {
|
|
|
|
- wacom->tool[0] = BTN_TOOL_RUBBER;
|
|
|
|
- wacom->id[0] = ERASER_DEVICE_ID;
|
|
|
|
- } else {
|
|
|
|
- wacom->tool[0] = BTN_TOOL_PEN;
|
|
|
|
- wacom->id[0] = STYLUS_DEVICE_ID;
|
|
|
|
- }
|
|
|
|
- wacom->shared->stylus_in_proximity = true;
|
|
|
|
|
|
+ if (!wacom->shared->stylus_in_proximity) {
|
|
|
|
+ if (data[1] & 0x08) {
|
|
|
|
+ wacom->tool[0] = BTN_TOOL_RUBBER;
|
|
|
|
+ wacom->id[0] = ERASER_DEVICE_ID;
|
|
|
|
+ } else {
|
|
|
|
+ wacom->tool[0] = BTN_TOOL_PEN;
|
|
|
|
+ wacom->id[0] = STYLUS_DEVICE_ID;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ wacom->shared->stylus_in_proximity = prox;
|
|
|
|
+ if (wacom->shared->touch_down)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (prox) {
|
|
x = le16_to_cpup((__le16 *)&data[2]);
|
|
x = le16_to_cpup((__le16 *)&data[2]);
|
|
y = le16_to_cpup((__le16 *)&data[4]);
|
|
y = le16_to_cpup((__le16 *)&data[4]);
|
|
p = le16_to_cpup((__le16 *)&data[6]);
|
|
p = le16_to_cpup((__le16 *)&data[6]);
|
|
@@ -1815,6 +1810,8 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
|
|
pen = data[1] & 0x01;
|
|
pen = data[1] & 0x01;
|
|
btn1 = data[1] & 0x02;
|
|
btn1 = data[1] & 0x02;
|
|
btn2 = data[1] & 0x04;
|
|
btn2 = data[1] & 0x04;
|
|
|
|
+ } else {
|
|
|
|
+ wacom->id[0] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
input_report_key(input, BTN_TOUCH, pen);
|
|
input_report_key(input, BTN_TOUCH, pen);
|
|
@@ -1826,11 +1823,6 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
|
|
input_report_abs(input, ABS_PRESSURE, p);
|
|
input_report_abs(input, ABS_PRESSURE, p);
|
|
input_report_abs(input, ABS_DISTANCE, d);
|
|
input_report_abs(input, ABS_DISTANCE, d);
|
|
|
|
|
|
- if (!prox) {
|
|
|
|
- wacom->id[0] = 0;
|
|
|
|
- wacom->shared->stylus_in_proximity = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
|
|
input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
|
|
input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
|
|
input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
|
|
|
|
|
|
@@ -1849,6 +1841,91 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom,
|
|
|
|
+ unsigned char *data)
|
|
|
|
+{
|
|
|
|
+ unsigned char prefix;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * We need to reroute the event from the debug interface to the
|
|
|
|
+ * pen interface.
|
|
|
|
+ * We need to add the report ID to the actual pen report, so we
|
|
|
|
+ * temporary overwrite the first byte to prevent having to kzalloc/kfree
|
|
|
|
+ * and memcpy the report.
|
|
|
|
+ */
|
|
|
|
+ prefix = data[0];
|
|
|
|
+ data[0] = WACOM_REPORT_BPAD_PEN;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * actually reroute the event.
|
|
|
|
+ * No need to check if wacom->shared->pen is valid, hid_input_report()
|
|
|
|
+ * will check for us.
|
|
|
|
+ */
|
|
|
|
+ hid_input_report(wacom->shared->pen, HID_INPUT_REPORT, data,
|
|
|
|
+ WACOM_PKGLEN_PENABLED, 1);
|
|
|
|
+
|
|
|
|
+ data[0] = prefix;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom,
|
|
|
|
+ unsigned char *data)
|
|
|
|
+{
|
|
|
|
+ struct input_dev *input = wacom->input;
|
|
|
|
+ unsigned char *finger_data, prefix;
|
|
|
|
+ unsigned id;
|
|
|
|
+ int x, y;
|
|
|
|
+ bool valid;
|
|
|
|
+
|
|
|
|
+ prefix = data[0];
|
|
|
|
+
|
|
|
|
+ for (id = 0; id < wacom->features.touch_max; id++) {
|
|
|
|
+ valid = !!(prefix & BIT(id)) &&
|
|
|
|
+ !wacom->shared->stylus_in_proximity;
|
|
|
|
+
|
|
|
|
+ input_mt_slot(input, id);
|
|
|
|
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, valid);
|
|
|
|
+
|
|
|
|
+ if (!valid)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ finger_data = data + 1 + id * 3;
|
|
|
|
+ x = finger_data[0] | ((finger_data[1] & 0x0f) << 8);
|
|
|
|
+ y = (finger_data[2] << 4) | (finger_data[1] >> 4);
|
|
|
|
+
|
|
|
|
+ input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
|
|
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ input_mt_sync_frame(input);
|
|
|
|
+
|
|
|
|
+ input_report_key(input, BTN_LEFT, prefix & 0x40);
|
|
|
|
+ input_report_key(input, BTN_RIGHT, prefix & 0x80);
|
|
|
|
+
|
|
|
|
+ /* keep touch state for pen event */
|
|
|
|
+ wacom->shared->touch_down = !!prefix &&
|
|
|
|
+ !wacom->shared->stylus_in_proximity;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int wacom_bamboo_pad_irq(struct wacom_wac *wacom, size_t len)
|
|
|
|
+{
|
|
|
|
+ unsigned char *data = wacom->data;
|
|
|
|
+
|
|
|
|
+ if (!((len == WACOM_PKGLEN_BPAD_TOUCH) ||
|
|
|
|
+ (len == WACOM_PKGLEN_BPAD_TOUCH_USB)) ||
|
|
|
|
+ (data[0] != WACOM_REPORT_BPAD_TOUCH))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (data[1] & 0x01)
|
|
|
|
+ wacom_bamboo_pad_pen_event(wacom, &data[1]);
|
|
|
|
+
|
|
|
|
+ if (data[1] & 0x02)
|
|
|
|
+ return wacom_bamboo_pad_touch_event(wacom, &data[9]);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
|
|
static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
|
|
{
|
|
{
|
|
unsigned char *data = wacom->data;
|
|
unsigned char *data = wacom->data;
|
|
@@ -1859,7 +1936,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
|
|
|
|
|
|
connected = data[1] & 0x01;
|
|
connected = data[1] & 0x01;
|
|
if (connected) {
|
|
if (connected) {
|
|
- int pid, battery, ps_connected;
|
|
|
|
|
|
+ int pid, battery, charging;
|
|
|
|
|
|
if ((wacom->shared->type == INTUOSHT) &&
|
|
if ((wacom->shared->type == INTUOSHT) &&
|
|
wacom->shared->touch_input &&
|
|
wacom->shared->touch_input &&
|
|
@@ -1871,30 +1948,63 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
|
|
|
|
|
|
pid = get_unaligned_be16(&data[6]);
|
|
pid = get_unaligned_be16(&data[6]);
|
|
battery = (data[5] & 0x3f) * 100 / 31;
|
|
battery = (data[5] & 0x3f) * 100 / 31;
|
|
- ps_connected = !!(data[5] & 0x80);
|
|
|
|
|
|
+ charging = !!(data[5] & 0x80);
|
|
if (wacom->pid != pid) {
|
|
if (wacom->pid != pid) {
|
|
wacom->pid = pid;
|
|
wacom->pid = pid;
|
|
wacom_schedule_work(wacom);
|
|
wacom_schedule_work(wacom);
|
|
}
|
|
}
|
|
|
|
|
|
- if (wacom->shared->type &&
|
|
|
|
- (battery != wacom->battery_capacity ||
|
|
|
|
- ps_connected != wacom->ps_connected)) {
|
|
|
|
- wacom->battery_capacity = battery;
|
|
|
|
- wacom->ps_connected = ps_connected;
|
|
|
|
- wacom->bat_charging = ps_connected &&
|
|
|
|
- wacom->battery_capacity < 100;
|
|
|
|
- wacom_notify_battery(wacom);
|
|
|
|
- }
|
|
|
|
|
|
+ if (wacom->shared->type)
|
|
|
|
+ wacom_notify_battery(wacom, battery, charging, 1, 0);
|
|
|
|
+
|
|
} else if (wacom->pid != 0) {
|
|
} else if (wacom->pid != 0) {
|
|
/* disconnected while previously connected */
|
|
/* disconnected while previously connected */
|
|
wacom->pid = 0;
|
|
wacom->pid = 0;
|
|
wacom_schedule_work(wacom);
|
|
wacom_schedule_work(wacom);
|
|
- wacom->battery_capacity = 0;
|
|
|
|
- wacom->bat_charging = 0;
|
|
|
|
- wacom->ps_connected = 0;
|
|
|
|
|
|
+ wacom_notify_battery(wacom, 0, 0, 0, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)
|
|
|
|
+{
|
|
|
|
+ struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
|
|
|
|
+ struct wacom_features *features = &wacom_wac->features;
|
|
|
|
+ unsigned char *data = wacom_wac->data;
|
|
|
|
+
|
|
|
|
+ if (data[0] != WACOM_REPORT_USB)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (features->type == INTUOSHT &&
|
|
|
|
+ wacom_wac->shared->touch_input &&
|
|
|
|
+ features->touch_max) {
|
|
|
|
+ input_report_switch(wacom_wac->shared->touch_input,
|
|
|
|
+ SW_MUTE_DEVICE, data[8] & 0x40);
|
|
|
|
+ input_sync(wacom_wac->shared->touch_input);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (data[9] & 0x02) { /* wireless module is attached */
|
|
|
|
+ int battery = (data[8] & 0x3f) * 100 / 31;
|
|
|
|
+ bool charging = !!(data[8] & 0x80);
|
|
|
|
+
|
|
|
|
+ wacom_notify_battery(wacom_wac, battery, charging,
|
|
|
|
+ battery || charging, 1);
|
|
|
|
+
|
|
|
|
+ if (!wacom->battery &&
|
|
|
|
+ !(features->quirks & WACOM_QUIRK_BATTERY)) {
|
|
|
|
+ features->quirks |= WACOM_QUIRK_BATTERY;
|
|
|
|
+ INIT_WORK(&wacom->work, wacom_battery_work);
|
|
|
|
+ wacom_schedule_work(wacom_wac);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if ((features->quirks & WACOM_QUIRK_BATTERY) &&
|
|
|
|
+ wacom->battery) {
|
|
|
|
+ features->quirks &= ~WACOM_QUIRK_BATTERY;
|
|
|
|
+ INIT_WORK(&wacom->work, wacom_battery_work);
|
|
|
|
+ wacom_schedule_work(wacom_wac);
|
|
|
|
+ wacom_notify_battery(wacom_wac, 0, 0, 0, 0);
|
|
|
|
+ }
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1967,6 +2077,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
|
|
case INTUOSPL:
|
|
case INTUOSPL:
|
|
if (len == WACOM_PKGLEN_BBTOUCH3)
|
|
if (len == WACOM_PKGLEN_BBTOUCH3)
|
|
sync = wacom_bpt3_touch(wacom_wac);
|
|
sync = wacom_bpt3_touch(wacom_wac);
|
|
|
|
+ else if (wacom_wac->data[0] == WACOM_REPORT_USB)
|
|
|
|
+ sync = wacom_status_irq(wacom_wac, len);
|
|
else
|
|
else
|
|
sync = wacom_intuos_irq(wacom_wac);
|
|
sync = wacom_intuos_irq(wacom_wac);
|
|
break;
|
|
break;
|
|
@@ -1982,7 +2094,14 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
|
|
|
|
|
|
case BAMBOO_PT:
|
|
case BAMBOO_PT:
|
|
case INTUOSHT:
|
|
case INTUOSHT:
|
|
- sync = wacom_bpt_irq(wacom_wac, len);
|
|
|
|
|
|
+ if (wacom_wac->data[0] == WACOM_REPORT_USB)
|
|
|
|
+ sync = wacom_status_irq(wacom_wac, len);
|
|
|
|
+ else
|
|
|
|
+ sync = wacom_bpt_irq(wacom_wac, len);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case BAMBOO_PAD:
|
|
|
|
+ sync = wacom_bamboo_pad_irq(wacom_wac, len);
|
|
break;
|
|
break;
|
|
|
|
|
|
case WIRELESS:
|
|
case WIRELESS:
|
|
@@ -2054,12 +2173,6 @@ void wacom_setup_device_quirks(struct wacom_features *features)
|
|
features->y_max = 1023;
|
|
features->y_max = 1023;
|
|
}
|
|
}
|
|
|
|
|
|
- /* these device have multiple inputs */
|
|
|
|
- if (features->type >= WIRELESS ||
|
|
|
|
- (features->type >= INTUOS5S && features->type <= INTUOSHT) ||
|
|
|
|
- (features->oVid && features->oPid))
|
|
|
|
- features->quirks |= WACOM_QUIRK_MULTI_INPUT;
|
|
|
|
-
|
|
|
|
/* quirk for bamboo touch with 2 low res touches */
|
|
/* quirk for bamboo touch with 2 low res touches */
|
|
if (features->type == BAMBOO_PT &&
|
|
if (features->type == BAMBOO_PT &&
|
|
features->pktlen == WACOM_PKGLEN_BBTOUCH) {
|
|
features->pktlen == WACOM_PKGLEN_BBTOUCH) {
|
|
@@ -2323,6 +2436,13 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
|
|
0, 0);
|
|
0, 0);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case BAMBOO_PAD:
|
|
|
|
+ __clear_bit(ABS_MISC, input_dev->absbit);
|
|
|
|
+ input_mt_init_slots(input_dev, features->touch_max,
|
|
|
|
+ INPUT_MT_POINTER);
|
|
|
|
+ __set_bit(BTN_LEFT, input_dev->keybit);
|
|
|
|
+ __set_bit(BTN_RIGHT, input_dev->keybit);
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -2772,6 +2892,15 @@ static const struct wacom_features wacom_features_0x304 =
|
|
{ "Wacom Cintiq 13HD", 59152, 33448, 1023, 63,
|
|
{ "Wacom Cintiq 13HD", 59152, 33448, 1023, 63,
|
|
WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|
|
WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|
|
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
|
|
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
|
|
|
|
+static const struct wacom_features wacom_features_0x333 =
|
|
|
|
+ { "Wacom Cintiq 13HD touch", 59152, 33448, 2047, 63,
|
|
|
|
+ WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|
|
|
|
+ WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
|
|
|
|
+ .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x335 };
|
|
|
|
+static const struct wacom_features wacom_features_0x335 =
|
|
|
|
+ { "Wacom Cintiq 13HD touch", .type = WACOM_24HDT, /* Touch */
|
|
|
|
+ .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x333, .touch_max = 10,
|
|
|
|
+ .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
|
|
static const struct wacom_features wacom_features_0xC7 =
|
|
static const struct wacom_features wacom_features_0xC7 =
|
|
{ "Wacom DTU1931", 37832, 30305, 511, 0,
|
|
{ "Wacom DTU1931", 37832, 30305, 511, 0,
|
|
PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
|
|
PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
|
|
@@ -2976,6 +3105,12 @@ static const struct wacom_features wacom_features_0x30C =
|
|
{ "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */
|
|
{ "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */
|
|
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10,
|
|
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10,
|
|
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
|
|
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
|
|
|
|
+static const struct wacom_features wacom_features_0x318 =
|
|
|
|
+ { "Wacom USB Bamboo PAD", 4095, 4095, /* Touch */
|
|
|
|
+ .type = BAMBOO_PAD, 35, 48, .touch_max = 4 };
|
|
|
|
+static const struct wacom_features wacom_features_0x319 =
|
|
|
|
+ { "Wacom Wireless Bamboo PAD", 4095, 4095, /* Touch */
|
|
|
|
+ .type = BAMBOO_PAD, 35, 48, .touch_max = 4 };
|
|
static const struct wacom_features wacom_features_0x323 =
|
|
static const struct wacom_features wacom_features_0x323 =
|
|
{ "Wacom Intuos P M", 21600, 13500, 1023, 31,
|
|
{ "Wacom Intuos P M", 21600, 13500, 1023, 31,
|
|
INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
|
|
INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
|
|
@@ -2992,6 +3127,10 @@ static const struct wacom_features wacom_features_HID_ANY_ID =
|
|
HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
|
|
HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
|
|
.driver_data = (kernel_ulong_t)&wacom_features_##prod
|
|
.driver_data = (kernel_ulong_t)&wacom_features_##prod
|
|
|
|
|
|
|
|
+#define I2C_DEVICE_WACOM(prod) \
|
|
|
|
+ HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
|
|
|
|
+ .driver_data = (kernel_ulong_t)&wacom_features_##prod
|
|
|
|
+
|
|
#define USB_DEVICE_LENOVO(prod) \
|
|
#define USB_DEVICE_LENOVO(prod) \
|
|
HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \
|
|
HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \
|
|
.driver_data = (kernel_ulong_t)&wacom_features_##prod
|
|
.driver_data = (kernel_ulong_t)&wacom_features_##prod
|
|
@@ -3124,11 +3263,15 @@ const struct hid_device_id wacom_ids[] = {
|
|
{ USB_DEVICE_WACOM(0x314) },
|
|
{ USB_DEVICE_WACOM(0x314) },
|
|
{ USB_DEVICE_WACOM(0x315) },
|
|
{ USB_DEVICE_WACOM(0x315) },
|
|
{ USB_DEVICE_WACOM(0x317) },
|
|
{ USB_DEVICE_WACOM(0x317) },
|
|
|
|
+ { USB_DEVICE_WACOM(0x318) },
|
|
|
|
+ { USB_DEVICE_WACOM(0x319) },
|
|
{ USB_DEVICE_WACOM(0x323) },
|
|
{ USB_DEVICE_WACOM(0x323) },
|
|
{ USB_DEVICE_WACOM(0x32A) },
|
|
{ USB_DEVICE_WACOM(0x32A) },
|
|
{ USB_DEVICE_WACOM(0x32B) },
|
|
{ USB_DEVICE_WACOM(0x32B) },
|
|
{ USB_DEVICE_WACOM(0x32C) },
|
|
{ USB_DEVICE_WACOM(0x32C) },
|
|
{ USB_DEVICE_WACOM(0x32F) },
|
|
{ USB_DEVICE_WACOM(0x32F) },
|
|
|
|
+ { USB_DEVICE_WACOM(0x333) },
|
|
|
|
+ { USB_DEVICE_WACOM(0x335) },
|
|
{ USB_DEVICE_WACOM(0x4001) },
|
|
{ USB_DEVICE_WACOM(0x4001) },
|
|
{ USB_DEVICE_WACOM(0x4004) },
|
|
{ USB_DEVICE_WACOM(0x4004) },
|
|
{ USB_DEVICE_WACOM(0x5000) },
|
|
{ USB_DEVICE_WACOM(0x5000) },
|
|
@@ -3136,6 +3279,7 @@ const struct hid_device_id wacom_ids[] = {
|
|
{ USB_DEVICE_LENOVO(0x6004) },
|
|
{ USB_DEVICE_LENOVO(0x6004) },
|
|
|
|
|
|
{ USB_DEVICE_WACOM(HID_ANY_ID) },
|
|
{ USB_DEVICE_WACOM(HID_ANY_ID) },
|
|
|
|
+ { I2C_DEVICE_WACOM(HID_ANY_ID) },
|
|
{ }
|
|
{ }
|
|
};
|
|
};
|
|
MODULE_DEVICE_TABLE(hid, wacom_ids);
|
|
MODULE_DEVICE_TABLE(hid, wacom_ids);
|