aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet/wacom_wac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/tablet/wacom_wac.c')
-rw-r--r--drivers/input/tablet/wacom_wac.c305
1 files changed, 128 insertions, 177 deletions
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 435b0af401e..5597637cfd4 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -14,6 +14,7 @@
14 14
15#include "wacom_wac.h" 15#include "wacom_wac.h"
16#include "wacom.h" 16#include "wacom.h"
17#include <linux/input/mt.h>
17 18
18static int wacom_penpartner_irq(struct wacom_wac *wacom) 19static int wacom_penpartner_irq(struct wacom_wac *wacom)
19{ 20{
@@ -674,169 +675,87 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
674 return 1; 675 return 1;
675} 676}
676 677
677 678static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
678static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx)
679{ 679{
680 struct input_dev *input = wacom->input; 680 struct input_dev *input = wacom->input;
681 int finger = idx + 1; 681 unsigned char *data = wacom->data;
682 int x = le16_to_cpup((__le16 *)&data[finger * 2]) & 0x7fff; 682 int contact_with_no_pen_down_count = 0;
683 int y = le16_to_cpup((__le16 *)&data[4 + finger * 2]) & 0x7fff; 683 int i;
684 684
685 /* 685 for (i = 0; i < 2; i++) {
686 * Work around input core suppressing "duplicate" events since 686 int p = data[1] & (1 << i);
687 * we are abusing ABS_X/ABS_Y to transmit multi-finger data. 687 bool touch = p && !wacom->shared->stylus_in_proximity;
688 * This should go away once we switch to true multitouch
689 * protocol.
690 */
691 if (wacom->last_finger != finger) {
692 if (x == input_abs_get_val(input, ABS_X))
693 x++;
694 688
695 if (y == input_abs_get_val(input, ABS_Y)) 689 input_mt_slot(input, i);
696 y++; 690 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
691 if (touch) {
692 int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff;
693 int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff;
694
695 input_report_abs(input, ABS_MT_POSITION_X, x);
696 input_report_abs(input, ABS_MT_POSITION_Y, y);
697 contact_with_no_pen_down_count++;
698 }
697 } 699 }
698 700
699 input_report_abs(input, ABS_X, x); 701 /* keep touch state for pen event */
700 input_report_abs(input, ABS_Y, y); 702 wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
701 input_report_abs(input, ABS_MISC, wacom->id[0]);
702 input_report_key(input, wacom->tool[finger], 1);
703 if (!idx)
704 input_report_key(input, BTN_TOUCH, 1);
705 input_event(input, EV_MSC, MSC_SERIAL, finger);
706 input_sync(input);
707 703
708 wacom->last_finger = finger; 704 input_mt_report_pointer_emulation(input, true);
709}
710 705
711static void wacom_tpc_touch_out(struct wacom_wac *wacom, int idx) 706 return 1;
712{
713 struct input_dev *input = wacom->input;
714 int finger = idx + 1;
715
716 input_report_abs(input, ABS_X, 0);
717 input_report_abs(input, ABS_Y, 0);
718 input_report_abs(input, ABS_MISC, 0);
719 input_report_key(input, wacom->tool[finger], 0);
720 if (!idx)
721 input_report_key(input, BTN_TOUCH, 0);
722 input_event(input, EV_MSC, MSC_SERIAL, finger);
723 input_sync(input);
724} 707}
725 708
726static void wacom_tpc_touch_in(struct wacom_wac *wacom, size_t len) 709static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
727{ 710{
728 char *data = wacom->data; 711 char *data = wacom->data;
729 struct input_dev *input = wacom->input; 712 struct input_dev *input = wacom->input;
713 bool prox;
714 int x = 0, y = 0;
730 715
731 wacom->tool[1] = BTN_TOOL_DOUBLETAP; 716 if (!wacom->shared->stylus_in_proximity) {
732 wacom->id[0] = TOUCH_DEVICE_ID; 717 if (len == WACOM_PKGLEN_TPC1FG) {
733 wacom->tool[2] = BTN_TOOL_TRIPLETAP; 718 prox = data[0] & 0x01;
734 719 x = get_unaligned_le16(&data[1]);
735 if (len != WACOM_PKGLEN_TPC1FG) { 720 y = get_unaligned_le16(&data[3]);
736 721 } else { /* with capacity */
737 switch (data[0]) { 722 prox = data[1] & 0x01;
723 x = le16_to_cpup((__le16 *)&data[2]);
724 y = le16_to_cpup((__le16 *)&data[4]);
725 }
726 } else
727 /* force touch out when pen is in prox */
728 prox = 0;
738 729
739 case WACOM_REPORT_TPC1FG: 730 if (prox) {
740 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); 731 input_report_abs(input, ABS_X, x);
741 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); 732 input_report_abs(input, ABS_Y, y);
742 input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); 733 }
743 input_report_key(input, BTN_TOUCH, le16_to_cpup((__le16 *)&data[6])); 734 input_report_key(input, BTN_TOUCH, prox);
744 input_report_abs(input, ABS_MISC, wacom->id[0]);
745 input_report_key(input, wacom->tool[1], 1);
746 input_sync(input);
747 break;
748 735
749 case WACOM_REPORT_TPC2FG: 736 /* keep touch state for pen events */
750 if (data[1] & 0x01) 737 wacom->shared->touch_down = prox;
751 wacom_tpc_finger_in(wacom, data, 0);
752 else if (wacom->id[1] & 0x01)
753 wacom_tpc_touch_out(wacom, 0);
754 738
755 if (data[1] & 0x02) 739 return 1;
756 wacom_tpc_finger_in(wacom, data, 1);
757 else if (wacom->id[1] & 0x02)
758 wacom_tpc_touch_out(wacom, 1);
759 break;
760 }
761 } else {
762 input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
763 input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
764 input_report_key(input, BTN_TOUCH, 1);
765 input_report_abs(input, ABS_MISC, wacom->id[1]);
766 input_report_key(input, wacom->tool[1], 1);
767 input_sync(input);
768 }
769} 740}
770 741
771static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) 742static int wacom_tpc_pen(struct wacom_wac *wacom)
772{ 743{
773 struct wacom_features *features = &wacom->features; 744 struct wacom_features *features = &wacom->features;
774 char *data = wacom->data; 745 char *data = wacom->data;
775 struct input_dev *input = wacom->input; 746 struct input_dev *input = wacom->input;
776 int prox = 0, pressure; 747 int pressure;
777 int retval = 0; 748 bool prox = data[1] & 0x20;
778
779 dbg("wacom_tpc_irq: received report #%d", data[0]);
780
781 if (len == WACOM_PKGLEN_TPC1FG || /* single touch */
782 data[0] == WACOM_REPORT_TPC1FG || /* single touch */
783 data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */
784
785 if (wacom->shared->stylus_in_proximity) {
786 if (wacom->id[1] & 0x01)
787 wacom_tpc_touch_out(wacom, 0);
788
789 if (wacom->id[1] & 0x02)
790 wacom_tpc_touch_out(wacom, 1);
791
792 wacom->id[1] = 0;
793 return 0;
794 }
795
796 if (len == WACOM_PKGLEN_TPC1FG) { /* with touch */
797 prox = data[0] & 0x01;
798 } else { /* with capacity */
799 if (data[0] == WACOM_REPORT_TPC1FG)
800 /* single touch */
801 prox = data[1] & 0x01;
802 else
803 /* 2FG touch data */
804 prox = data[1] & 0x03;
805 }
806
807 if (prox) {
808 if (!wacom->id[1])
809 wacom->last_finger = 1;
810 wacom_tpc_touch_in(wacom, len);
811 } else {
812 if (data[0] == WACOM_REPORT_TPC2FG) {
813 /* 2FGT out-prox */
814 if (wacom->id[1] & 0x01)
815 wacom_tpc_touch_out(wacom, 0);
816 749
817 if (wacom->id[1] & 0x02) 750 if (!wacom->shared->stylus_in_proximity) /* first in prox */
818 wacom_tpc_touch_out(wacom, 1); 751 /* Going into proximity select tool */
819 } else 752 wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
820 /* one finger touch */
821 wacom_tpc_touch_out(wacom, 0);
822 753
823 wacom->id[0] = 0; 754 /* keep pen state for touch events */
824 } 755 wacom->shared->stylus_in_proximity = prox;
825 /* keep prox bit to send proper out-prox event */
826 wacom->id[1] = prox;
827 } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */
828 prox = data[1] & 0x20;
829
830 if (!wacom->shared->stylus_in_proximity) { /* first in prox */
831 /* Going into proximity select tool */
832 wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
833 if (wacom->tool[0] == BTN_TOOL_PEN)
834 wacom->id[0] = STYLUS_DEVICE_ID;
835 else
836 wacom->id[0] = ERASER_DEVICE_ID;
837 756
838 wacom->shared->stylus_in_proximity = true; 757 /* send pen events only when touch is up or forced out */
839 } 758 if (!wacom->shared->touch_down) {
840 input_report_key(input, BTN_STYLUS, data[1] & 0x02); 759 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
841 input_report_key(input, BTN_STYLUS2, data[1] & 0x10); 760 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
842 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); 761 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
@@ -846,15 +765,27 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
846 pressure = features->pressure_max + pressure + 1; 765 pressure = features->pressure_max + pressure + 1;
847 input_report_abs(input, ABS_PRESSURE, pressure); 766 input_report_abs(input, ABS_PRESSURE, pressure);
848 input_report_key(input, BTN_TOUCH, data[1] & 0x05); 767 input_report_key(input, BTN_TOUCH, data[1] & 0x05);
849 if (!prox) { /* out-prox */
850 wacom->id[0] = 0;
851 wacom->shared->stylus_in_proximity = false;
852 }
853 input_report_key(input, wacom->tool[0], prox); 768 input_report_key(input, wacom->tool[0], prox);
854 input_report_abs(input, ABS_MISC, wacom->id[0]); 769 return 1;
855 retval = 1;
856 } 770 }
857 return retval; 771
772 return 0;
773}
774
775static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
776{
777 char *data = wacom->data;
778
779 dbg("wacom_tpc_irq: received report #%d", data[0]);
780
781 if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG)
782 return wacom_tpc_single_touch(wacom, len);
783 else if (data[0] == WACOM_REPORT_TPC2FG)
784 return wacom_tpc_mt_touch(wacom);
785 else if (data[0] == WACOM_REPORT_PENABLED)
786 return wacom_tpc_pen(wacom);
787
788 return 0;
858} 789}
859 790
860static int wacom_bpt_touch(struct wacom_wac *wacom) 791static int wacom_bpt_touch(struct wacom_wac *wacom)
@@ -862,19 +793,21 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
862 struct wacom_features *features = &wacom->features; 793 struct wacom_features *features = &wacom->features;
863 struct input_dev *input = wacom->input; 794 struct input_dev *input = wacom->input;
864 unsigned char *data = wacom->data; 795 unsigned char *data = wacom->data;
865 int sp = 0, sx = 0, sy = 0, count = 0;
866 int i; 796 int i;
867 797
868 for (i = 0; i < 2; i++) { 798 for (i = 0; i < 2; i++) {
869 int p = data[9 * i + 2]; 799 int p = data[9 * i + 2];
800 bool touch = p && !wacom->shared->stylus_in_proximity;
801
870 input_mt_slot(input, i); 802 input_mt_slot(input, i);
803 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
871 /* 804 /*
872 * Touch events need to be disabled while stylus is 805 * Touch events need to be disabled while stylus is
873 * in proximity because user's hand is resting on touchpad 806 * in proximity because user's hand is resting on touchpad
874 * and sending unwanted events. User expects tablet buttons 807 * and sending unwanted events. User expects tablet buttons
875 * to continue working though. 808 * to continue working though.
876 */ 809 */
877 if (p && !wacom->shared->stylus_in_proximity) { 810 if (touch) {
878 int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; 811 int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
879 int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; 812 int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
880 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { 813 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
@@ -884,23 +817,10 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
884 input_report_abs(input, ABS_MT_PRESSURE, p); 817 input_report_abs(input, ABS_MT_PRESSURE, p);
885 input_report_abs(input, ABS_MT_POSITION_X, x); 818 input_report_abs(input, ABS_MT_POSITION_X, x);
886 input_report_abs(input, ABS_MT_POSITION_Y, y); 819 input_report_abs(input, ABS_MT_POSITION_Y, y);
887 if (wacom->id[i] < 0)
888 wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
889 if (!count++)
890 sp = p, sx = x, sy = y;
891 } else {
892 wacom->id[i] = -1;
893 } 820 }
894 input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
895 } 821 }
896 822
897 input_report_key(input, BTN_TOUCH, count > 0); 823 input_mt_report_pointer_emulation(input, true);
898 input_report_key(input, BTN_TOOL_FINGER, count == 1);
899 input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);
900
901 input_report_abs(input, ABS_PRESSURE, sp);
902 input_report_abs(input, ABS_X, sx);
903 input_report_abs(input, ABS_Y, sy);
904 824
905 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); 825 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
906 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); 826 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
@@ -1088,7 +1008,7 @@ void wacom_setup_device_quirks(struct wacom_features *features)
1088{ 1008{
1089 1009
1090 /* touch device found but size is not defined. use default */ 1010 /* touch device found but size is not defined. use default */
1091 if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { 1011 if (features->device_type == BTN_TOOL_FINGER && !features->x_max) {
1092 features->x_max = 1023; 1012 features->x_max = 1023;
1093 features->y_max = 1023; 1013 features->y_max = 1023;
1094 } 1014 }
@@ -1100,7 +1020,7 @@ void wacom_setup_device_quirks(struct wacom_features *features)
1100 1020
1101 /* quirks for bamboo touch */ 1021 /* quirks for bamboo touch */
1102 if (features->type == BAMBOO_PT && 1022 if (features->type == BAMBOO_PT &&
1103 features->device_type == BTN_TOOL_TRIPLETAP) { 1023 features->device_type == BTN_TOOL_DOUBLETAP) {
1104 features->x_max <<= 5; 1024 features->x_max <<= 5;
1105 features->y_max <<= 5; 1025 features->y_max <<= 5;
1106 features->x_fuzz <<= 5; 1026 features->x_fuzz <<= 5;
@@ -1111,6 +1031,13 @@ void wacom_setup_device_quirks(struct wacom_features *features)
1111 } 1031 }
1112} 1032}
1113 1033
1034static unsigned int wacom_calculate_touch_res(unsigned int logical_max,
1035 unsigned int physical_max)
1036{
1037 /* Touch physical dimensions are in 100th of mm */
1038 return (logical_max * 100) / physical_max;
1039}
1040
1114void wacom_setup_input_capabilities(struct input_dev *input_dev, 1041void wacom_setup_input_capabilities(struct input_dev *input_dev,
1115 struct wacom_wac *wacom_wac) 1042 struct wacom_wac *wacom_wac)
1116{ 1043{
@@ -1229,23 +1156,30 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1229 break; 1156 break;
1230 1157
1231 case TABLETPC2FG: 1158 case TABLETPC2FG:
1232 if (features->device_type == BTN_TOOL_TRIPLETAP) { 1159 if (features->device_type == BTN_TOOL_DOUBLETAP) {
1233 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); 1160
1234 input_set_capability(input_dev, EV_MSC, MSC_SERIAL); 1161 input_mt_init_slots(input_dev, 2);
1162 input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
1163 0, MT_TOOL_MAX, 0, 0);
1164 input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1165 0, features->x_max, 0, 0);
1166 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
1167 0, features->y_max, 0, 0);
1235 } 1168 }
1236 /* fall through */ 1169 /* fall through */
1237 1170
1238 case TABLETPC: 1171 case TABLETPC:
1239 if (features->device_type == BTN_TOOL_DOUBLETAP || 1172 __clear_bit(ABS_MISC, input_dev->absbit);
1240 features->device_type == BTN_TOOL_TRIPLETAP) {
1241 input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0);
1242 input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0);
1243 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
1244 }
1245 1173
1246 if (features->device_type != BTN_TOOL_PEN) 1174 if (features->device_type != BTN_TOOL_PEN) {
1175 input_abs_set_res(input_dev, ABS_X,
1176 wacom_calculate_touch_res(features->x_max,
1177 features->x_phy));
1178 input_abs_set_res(input_dev, ABS_Y,
1179 wacom_calculate_touch_res(features->y_max,
1180 features->y_phy));
1247 break; /* no need to process stylus stuff */ 1181 break; /* no need to process stylus stuff */
1248 1182 }
1249 /* fall through */ 1183 /* fall through */
1250 1184
1251 case PL: 1185 case PL:
@@ -1263,7 +1197,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1263 case BAMBOO_PT: 1197 case BAMBOO_PT:
1264 __clear_bit(ABS_MISC, input_dev->absbit); 1198 __clear_bit(ABS_MISC, input_dev->absbit);
1265 1199
1266 if (features->device_type == BTN_TOOL_TRIPLETAP) { 1200 if (features->device_type == BTN_TOOL_DOUBLETAP) {
1267 __set_bit(BTN_LEFT, input_dev->keybit); 1201 __set_bit(BTN_LEFT, input_dev->keybit);
1268 __set_bit(BTN_FORWARD, input_dev->keybit); 1202 __set_bit(BTN_FORWARD, input_dev->keybit);
1269 __set_bit(BTN_BACK, input_dev->keybit); 1203 __set_bit(BTN_BACK, input_dev->keybit);
@@ -1272,7 +1206,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1272 __set_bit(BTN_TOOL_FINGER, input_dev->keybit); 1206 __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
1273 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); 1207 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
1274 1208
1275 input_mt_create_slots(input_dev, 2); 1209 input_mt_init_slots(input_dev, 2);
1276 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 1210 input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1277 0, features->x_max, 1211 0, features->x_max,
1278 features->x_fuzz, 0); 1212 features->x_fuzz, 0);
@@ -1282,8 +1216,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1282 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 1216 input_set_abs_params(input_dev, ABS_MT_PRESSURE,
1283 0, features->pressure_max, 1217 0, features->pressure_max,
1284 features->pressure_fuzz, 0); 1218 features->pressure_fuzz, 0);
1285 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 1219 input_abs_set_res(input_dev, ABS_X,
1286 MAX_TRACKING_ID, 0, 0); 1220 wacom_calculate_touch_res(features->x_max,
1221 features->x_phy));
1222 input_abs_set_res(input_dev, ABS_Y,
1223 wacom_calculate_touch_res(features->y_max,
1224 features->y_phy));
1287 } else if (features->device_type == BTN_TOOL_PEN) { 1225 } else if (features->device_type == BTN_TOOL_PEN) {
1288 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 1226 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1289 __set_bit(BTN_TOOL_PEN, input_dev->keybit); 1227 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
@@ -1438,17 +1376,27 @@ static struct wacom_features wacom_features_0xD3 =
1438 { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; 1376 { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
1439static const struct wacom_features wacom_features_0xD4 = 1377static const struct wacom_features wacom_features_0xD4 =
1440 { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT }; 1378 { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT };
1379static struct wacom_features wacom_features_0xD6 =
1380 { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
1381static struct wacom_features wacom_features_0xD7 =
1382 { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
1441static struct wacom_features wacom_features_0xD8 = 1383static struct wacom_features wacom_features_0xD8 =
1442 { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; 1384 { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
1443static struct wacom_features wacom_features_0xDA = 1385static struct wacom_features wacom_features_0xDA =
1444 { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; 1386 { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
1445static struct wacom_features wacom_features_0xDB = 1387static struct wacom_features wacom_features_0xDB =
1446 { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; 1388 { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
1389static const struct wacom_features wacom_features_0x6004 =
1390 { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, 0, TABLETPC };
1447 1391
1448#define USB_DEVICE_WACOM(prod) \ 1392#define USB_DEVICE_WACOM(prod) \
1449 USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ 1393 USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \
1450 .driver_info = (kernel_ulong_t)&wacom_features_##prod 1394 .driver_info = (kernel_ulong_t)&wacom_features_##prod
1451 1395
1396#define USB_DEVICE_LENOVO(prod) \
1397 USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \
1398 .driver_info = (kernel_ulong_t)&wacom_features_##prod
1399
1452const struct usb_device_id wacom_ids[] = { 1400const struct usb_device_id wacom_ids[] = {
1453 { USB_DEVICE_WACOM(0x00) }, 1401 { USB_DEVICE_WACOM(0x00) },
1454 { USB_DEVICE_WACOM(0x10) }, 1402 { USB_DEVICE_WACOM(0x10) },
@@ -1513,6 +1461,8 @@ const struct usb_device_id wacom_ids[] = {
1513 { USB_DEVICE_WACOM(0xD2) }, 1461 { USB_DEVICE_WACOM(0xD2) },
1514 { USB_DEVICE_WACOM(0xD3) }, 1462 { USB_DEVICE_WACOM(0xD3) },
1515 { USB_DEVICE_WACOM(0xD4) }, 1463 { USB_DEVICE_WACOM(0xD4) },
1464 { USB_DEVICE_WACOM(0xD6) },
1465 { USB_DEVICE_WACOM(0xD7) },
1516 { USB_DEVICE_WACOM(0xD8) }, 1466 { USB_DEVICE_WACOM(0xD8) },
1517 { USB_DEVICE_WACOM(0xDA) }, 1467 { USB_DEVICE_WACOM(0xDA) },
1518 { USB_DEVICE_WACOM(0xDB) }, 1468 { USB_DEVICE_WACOM(0xDB) },
@@ -1525,6 +1475,7 @@ const struct usb_device_id wacom_ids[] = {
1525 { USB_DEVICE_WACOM(0xE2) }, 1475 { USB_DEVICE_WACOM(0xE2) },
1526 { USB_DEVICE_WACOM(0xE3) }, 1476 { USB_DEVICE_WACOM(0xE3) },
1527 { USB_DEVICE_WACOM(0x47) }, 1477 { USB_DEVICE_WACOM(0x47) },
1478 { USB_DEVICE_LENOVO(0x6004) },
1528 { } 1479 { }
1529}; 1480};
1530MODULE_DEVICE_TABLE(usb, wacom_ids); 1481MODULE_DEVICE_TABLE(usb, wacom_ids);