diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-25 19:39:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-25 19:39:05 -0400 |
commit | c155c7492c9ab81f3d358a10eb4f29376ae53d85 (patch) | |
tree | 9aaebea333934de37ea4d0aa1b5e2e937ebe8a66 | |
parent | 1701f680407c6cc05121566cef5293d33881fe71 (diff) | |
parent | d314e9e80c5ea561b73584b73806c2ae9e30f503 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull more input updates from Dmitry Torokhov:
"Second round of updates for the input subsystem.
The BYD PS/2 protocol driver now uses absolute reporting mode and
should behave more like other touchpads; Synaptics driver needed to
extend one of its quirks to a newer firmware version, and a few USB
drivers got tightened up checks for the contents of their descriptors"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: sur40 - fix DMA on stack
Input: ati_remote2 - fix crashes on detecting device with invalid descriptor
Input: synaptics - handle spurious release of trackstick buttons, again
Input: synaptics-rmi4 - remove check of Non-NULL array
Input: byd - enable absolute mode
Input: ims-pcu - sanity check against missing interfaces
Input: melfas_mip4 - add hw_version sysfs attribute
-rw-r--r-- | drivers/input/misc/ati_remote2.c | 36 | ||||
-rw-r--r-- | drivers/input/misc/ims-pcu.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/byd.c | 565 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 5 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_driver.c | 5 | ||||
-rw-r--r-- | drivers/input/touchscreen/melfas_mip4.c | 28 | ||||
-rw-r--r-- | drivers/input/touchscreen/sur40.c | 21 |
8 files changed, 449 insertions, 217 deletions
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index cfd58e87da26..1c5914cae853 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -817,26 +817,49 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
817 | 817 | ||
818 | ar2->udev = udev; | 818 | ar2->udev = udev; |
819 | 819 | ||
820 | /* Sanity check, first interface must have an endpoint */ | ||
821 | if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { | ||
822 | dev_err(&interface->dev, | ||
823 | "%s(): interface 0 must have an endpoint\n", __func__); | ||
824 | r = -ENODEV; | ||
825 | goto fail1; | ||
826 | } | ||
820 | ar2->intf[0] = interface; | 827 | ar2->intf[0] = interface; |
821 | ar2->ep[0] = &alt->endpoint[0].desc; | 828 | ar2->ep[0] = &alt->endpoint[0].desc; |
822 | 829 | ||
830 | /* Sanity check, the device must have two interfaces */ | ||
823 | ar2->intf[1] = usb_ifnum_to_if(udev, 1); | 831 | ar2->intf[1] = usb_ifnum_to_if(udev, 1); |
832 | if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) { | ||
833 | dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n", | ||
834 | __func__, udev->actconfig->desc.bNumInterfaces); | ||
835 | r = -ENODEV; | ||
836 | goto fail1; | ||
837 | } | ||
838 | |||
824 | r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); | 839 | r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); |
825 | if (r) | 840 | if (r) |
826 | goto fail1; | 841 | goto fail1; |
842 | |||
843 | /* Sanity check, second interface must have an endpoint */ | ||
827 | alt = ar2->intf[1]->cur_altsetting; | 844 | alt = ar2->intf[1]->cur_altsetting; |
845 | if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { | ||
846 | dev_err(&interface->dev, | ||
847 | "%s(): interface 1 must have an endpoint\n", __func__); | ||
848 | r = -ENODEV; | ||
849 | goto fail2; | ||
850 | } | ||
828 | ar2->ep[1] = &alt->endpoint[0].desc; | 851 | ar2->ep[1] = &alt->endpoint[0].desc; |
829 | 852 | ||
830 | r = ati_remote2_urb_init(ar2); | 853 | r = ati_remote2_urb_init(ar2); |
831 | if (r) | 854 | if (r) |
832 | goto fail2; | 855 | goto fail3; |
833 | 856 | ||
834 | ar2->channel_mask = channel_mask; | 857 | ar2->channel_mask = channel_mask; |
835 | ar2->mode_mask = mode_mask; | 858 | ar2->mode_mask = mode_mask; |
836 | 859 | ||
837 | r = ati_remote2_setup(ar2, ar2->channel_mask); | 860 | r = ati_remote2_setup(ar2, ar2->channel_mask); |
838 | if (r) | 861 | if (r) |
839 | goto fail2; | 862 | goto fail3; |
840 | 863 | ||
841 | usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); | 864 | usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); |
842 | strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); | 865 | strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); |
@@ -845,11 +868,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
845 | 868 | ||
846 | r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); | 869 | r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); |
847 | if (r) | 870 | if (r) |
848 | goto fail2; | 871 | goto fail3; |
849 | 872 | ||
850 | r = ati_remote2_input_init(ar2); | 873 | r = ati_remote2_input_init(ar2); |
851 | if (r) | 874 | if (r) |
852 | goto fail3; | 875 | goto fail4; |
853 | 876 | ||
854 | usb_set_intfdata(interface, ar2); | 877 | usb_set_intfdata(interface, ar2); |
855 | 878 | ||
@@ -857,10 +880,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
857 | 880 | ||
858 | return 0; | 881 | return 0; |
859 | 882 | ||
860 | fail3: | 883 | fail4: |
861 | sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); | 884 | sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); |
862 | fail2: | 885 | fail3: |
863 | ati_remote2_urb_cleanup(ar2); | 886 | ati_remote2_urb_cleanup(ar2); |
887 | fail2: | ||
864 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | 888 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); |
865 | fail1: | 889 | fail1: |
866 | kfree(ar2); | 890 | kfree(ar2); |
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index ac1fa5f44580..9c0ea36913b4 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c | |||
@@ -1663,6 +1663,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc | |||
1663 | 1663 | ||
1664 | pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, | 1664 | pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, |
1665 | union_desc->bMasterInterface0); | 1665 | union_desc->bMasterInterface0); |
1666 | if (!pcu->ctrl_intf) | ||
1667 | return -EINVAL; | ||
1666 | 1668 | ||
1667 | alt = pcu->ctrl_intf->cur_altsetting; | 1669 | alt = pcu->ctrl_intf->cur_altsetting; |
1668 | pcu->ep_ctrl = &alt->endpoint[0].desc; | 1670 | pcu->ep_ctrl = &alt->endpoint[0].desc; |
@@ -1670,6 +1672,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc | |||
1670 | 1672 | ||
1671 | pcu->data_intf = usb_ifnum_to_if(pcu->udev, | 1673 | pcu->data_intf = usb_ifnum_to_if(pcu->udev, |
1672 | union_desc->bSlaveInterface0); | 1674 | union_desc->bSlaveInterface0); |
1675 | if (!pcu->data_intf) | ||
1676 | return -EINVAL; | ||
1673 | 1677 | ||
1674 | alt = pcu->data_intf->cur_altsetting; | 1678 | alt = pcu->data_intf->cur_altsetting; |
1675 | if (alt->desc.bNumEndpoints != 2) { | 1679 | if (alt->desc.bNumEndpoints != 2) { |
diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c index 9425e0f6c5ce..fdc243ca93ed 100644 --- a/drivers/input/mouse/byd.c +++ b/drivers/input/mouse/byd.c | |||
@@ -12,10 +12,12 @@ | |||
12 | #include <linux/input.h> | 12 | #include <linux/input.h> |
13 | #include <linux/libps2.h> | 13 | #include <linux/libps2.h> |
14 | #include <linux/serio.h> | 14 | #include <linux/serio.h> |
15 | #include <linux/slab.h> | ||
15 | 16 | ||
16 | #include "psmouse.h" | 17 | #include "psmouse.h" |
17 | #include "byd.h" | 18 | #include "byd.h" |
18 | 19 | ||
20 | /* PS2 Bits */ | ||
19 | #define PS2_Y_OVERFLOW BIT_MASK(7) | 21 | #define PS2_Y_OVERFLOW BIT_MASK(7) |
20 | #define PS2_X_OVERFLOW BIT_MASK(6) | 22 | #define PS2_X_OVERFLOW BIT_MASK(6) |
21 | #define PS2_Y_SIGN BIT_MASK(5) | 23 | #define PS2_Y_SIGN BIT_MASK(5) |
@@ -26,69 +28,249 @@ | |||
26 | #define PS2_LEFT BIT_MASK(0) | 28 | #define PS2_LEFT BIT_MASK(0) |
27 | 29 | ||
28 | /* | 30 | /* |
29 | * The touchpad reports gestures in the last byte of each packet. It can take | 31 | * BYD pad constants |
30 | * any of the following values: | ||
31 | */ | 32 | */ |
32 | 33 | ||
33 | /* One-finger scrolling in one of the edge scroll zones. */ | 34 | /* |
34 | #define BYD_SCROLLUP 0xCA | 35 | * True device resolution is unknown, however experiments show the |
35 | #define BYD_SCROLLDOWN 0x36 | 36 | * resolution is about 111 units/mm. |
36 | #define BYD_SCROLLLEFT 0xCB | 37 | * Absolute coordinate packets are in the range 0-255 for both X and Y |
37 | #define BYD_SCROLLRIGHT 0x35 | 38 | * we pick ABS_X/ABS_Y dimensions which are multiples of 256 and in |
38 | /* Two-finger scrolling. */ | 39 | * the right ballpark given the touchpad's physical dimensions and estimate |
39 | #define BYD_2DOWN 0x2B | 40 | * resolution per spec sheet, device active area dimensions are |
40 | #define BYD_2UP 0xD5 | 41 | * 101.6 x 60.1 mm. |
41 | #define BYD_2LEFT 0xD6 | 42 | */ |
42 | #define BYD_2RIGHT 0x2A | 43 | #define BYD_PAD_WIDTH 11264 |
43 | /* Pinching in or out. */ | 44 | #define BYD_PAD_HEIGHT 6656 |
44 | #define BYD_ZOOMOUT 0xD8 | 45 | #define BYD_PAD_RESOLUTION 111 |
45 | #define BYD_ZOOMIN 0x28 | ||
46 | /* Three-finger swipe. */ | ||
47 | #define BYD_3UP 0xD3 | ||
48 | #define BYD_3DOWN 0x2D | ||
49 | #define BYD_3LEFT 0xD4 | ||
50 | #define BYD_3RIGHT 0x2C | ||
51 | /* Four-finger swipe. */ | ||
52 | #define BYD_4UP 0xCD | ||
53 | #define BYD_4DOWN 0x33 | ||
54 | 46 | ||
55 | int byd_detect(struct psmouse *psmouse, bool set_properties) | 47 | /* |
48 | * Given the above dimensions, relative packets velocity is in multiples of | ||
49 | * 1 unit / 11 milliseconds. We use this dt to estimate distance traveled | ||
50 | */ | ||
51 | #define BYD_DT 11 | ||
52 | /* Time in jiffies used to timeout various touch events (64 ms) */ | ||
53 | #define BYD_TOUCH_TIMEOUT msecs_to_jiffies(64) | ||
54 | |||
55 | /* BYD commands reverse engineered from windows driver */ | ||
56 | |||
57 | /* | ||
58 | * Swipe gesture from off-pad to on-pad | ||
59 | * 0 : disable | ||
60 | * 1 : enable | ||
61 | */ | ||
62 | #define BYD_CMD_SET_OFFSCREEN_SWIPE 0x10cc | ||
63 | /* | ||
64 | * Tap and drag delay time | ||
65 | * 0 : disable | ||
66 | * 1 - 8 : least to most delay | ||
67 | */ | ||
68 | #define BYD_CMD_SET_TAP_DRAG_DELAY_TIME 0x10cf | ||
69 | /* | ||
70 | * Physical buttons function mapping | ||
71 | * 0 : enable | ||
72 | * 4 : normal | ||
73 | * 5 : left button custom command | ||
74 | * 6 : right button custom command | ||
75 | * 8 : disable | ||
76 | */ | ||
77 | #define BYD_CMD_SET_PHYSICAL_BUTTONS 0x10d0 | ||
78 | /* | ||
79 | * Absolute mode (1 byte X/Y resolution) | ||
80 | * 0 : disable | ||
81 | * 2 : enable | ||
82 | */ | ||
83 | #define BYD_CMD_SET_ABSOLUTE_MODE 0x10d1 | ||
84 | /* | ||
85 | * Two finger scrolling | ||
86 | * 1 : vertical | ||
87 | * 2 : horizontal | ||
88 | * 3 : vertical + horizontal | ||
89 | * 4 : disable | ||
90 | */ | ||
91 | #define BYD_CMD_SET_TWO_FINGER_SCROLL 0x10d2 | ||
92 | /* | ||
93 | * Handedness | ||
94 | * 1 : right handed | ||
95 | * 2 : left handed | ||
96 | */ | ||
97 | #define BYD_CMD_SET_HANDEDNESS 0x10d3 | ||
98 | /* | ||
99 | * Tap to click | ||
100 | * 1 : enable | ||
101 | * 2 : disable | ||
102 | */ | ||
103 | #define BYD_CMD_SET_TAP 0x10d4 | ||
104 | /* | ||
105 | * Tap and drag | ||
106 | * 1 : tap and hold to drag | ||
107 | * 2 : tap and hold to drag + lock | ||
108 | * 3 : disable | ||
109 | */ | ||
110 | #define BYD_CMD_SET_TAP_DRAG 0x10d5 | ||
111 | /* | ||
112 | * Touch sensitivity | ||
113 | * 1 - 7 : least to most sensitive | ||
114 | */ | ||
115 | #define BYD_CMD_SET_TOUCH_SENSITIVITY 0x10d6 | ||
116 | /* | ||
117 | * One finger scrolling | ||
118 | * 1 : vertical | ||
119 | * 2 : horizontal | ||
120 | * 3 : vertical + horizontal | ||
121 | * 4 : disable | ||
122 | */ | ||
123 | #define BYD_CMD_SET_ONE_FINGER_SCROLL 0x10d7 | ||
124 | /* | ||
125 | * One finger scrolling function | ||
126 | * 1 : free scrolling | ||
127 | * 2 : edge motion | ||
128 | * 3 : free scrolling + edge motion | ||
129 | * 4 : disable | ||
130 | */ | ||
131 | #define BYD_CMD_SET_ONE_FINGER_SCROLL_FUNC 0x10d8 | ||
132 | /* | ||
133 | * Sliding speed | ||
134 | * 1 - 5 : slowest to fastest | ||
135 | */ | ||
136 | #define BYD_CMD_SET_SLIDING_SPEED 0x10da | ||
137 | /* | ||
138 | * Edge motion | ||
139 | * 1 : disable | ||
140 | * 2 : enable when dragging | ||
141 | * 3 : enable when dragging and pointing | ||
142 | */ | ||
143 | #define BYD_CMD_SET_EDGE_MOTION 0x10db | ||
144 | /* | ||
145 | * Left edge region size | ||
146 | * 0 - 7 : smallest to largest width | ||
147 | */ | ||
148 | #define BYD_CMD_SET_LEFT_EDGE_REGION 0x10dc | ||
149 | /* | ||
150 | * Top edge region size | ||
151 | * 0 - 9 : smallest to largest height | ||
152 | */ | ||
153 | #define BYD_CMD_SET_TOP_EDGE_REGION 0x10dd | ||
154 | /* | ||
155 | * Disregard palm press as clicks | ||
156 | * 1 - 6 : smallest to largest | ||
157 | */ | ||
158 | #define BYD_CMD_SET_PALM_CHECK 0x10de | ||
159 | /* | ||
160 | * Right edge region size | ||
161 | * 0 - 7 : smallest to largest width | ||
162 | */ | ||
163 | #define BYD_CMD_SET_RIGHT_EDGE_REGION 0x10df | ||
164 | /* | ||
165 | * Bottom edge region size | ||
166 | * 0 - 9 : smallest to largest height | ||
167 | */ | ||
168 | #define BYD_CMD_SET_BOTTOM_EDGE_REGION 0x10e1 | ||
169 | /* | ||
170 | * Multitouch gestures | ||
171 | * 1 : enable | ||
172 | * 2 : disable | ||
173 | */ | ||
174 | #define BYD_CMD_SET_MULTITOUCH 0x10e3 | ||
175 | /* | ||
176 | * Edge motion speed | ||
177 | * 0 : control with finger pressure | ||
178 | * 1 - 9 : slowest to fastest | ||
179 | */ | ||
180 | #define BYD_CMD_SET_EDGE_MOTION_SPEED 0x10e4 | ||
181 | /* | ||
182 | * Two finger scolling function | ||
183 | * 0 : free scrolling | ||
184 | * 1 : free scrolling (with momentum) | ||
185 | * 2 : edge motion | ||
186 | * 3 : free scrolling (with momentum) + edge motion | ||
187 | * 4 : disable | ||
188 | */ | ||
189 | #define BYD_CMD_SET_TWO_FINGER_SCROLL_FUNC 0x10e5 | ||
190 | |||
191 | /* | ||
192 | * The touchpad generates a mixture of absolute and relative packets, indicated | ||
193 | * by the the last byte of each packet being set to one of the following: | ||
194 | */ | ||
195 | #define BYD_PACKET_ABSOLUTE 0xf8 | ||
196 | #define BYD_PACKET_RELATIVE 0x00 | ||
197 | /* Multitouch gesture packets */ | ||
198 | #define BYD_PACKET_PINCH_IN 0xd8 | ||
199 | #define BYD_PACKET_PINCH_OUT 0x28 | ||
200 | #define BYD_PACKET_ROTATE_CLOCKWISE 0x29 | ||
201 | #define BYD_PACKET_ROTATE_ANTICLOCKWISE 0xd7 | ||
202 | #define BYD_PACKET_TWO_FINGER_SCROLL_RIGHT 0x2a | ||
203 | #define BYD_PACKET_TWO_FINGER_SCROLL_DOWN 0x2b | ||
204 | #define BYD_PACKET_TWO_FINGER_SCROLL_UP 0xd5 | ||
205 | #define BYD_PACKET_TWO_FINGER_SCROLL_LEFT 0xd6 | ||
206 | #define BYD_PACKET_THREE_FINGER_SWIPE_RIGHT 0x2c | ||
207 | #define BYD_PACKET_THREE_FINGER_SWIPE_DOWN 0x2d | ||
208 | #define BYD_PACKET_THREE_FINGER_SWIPE_UP 0xd3 | ||
209 | #define BYD_PACKET_THREE_FINGER_SWIPE_LEFT 0xd4 | ||
210 | #define BYD_PACKET_FOUR_FINGER_DOWN 0x33 | ||
211 | #define BYD_PACKET_FOUR_FINGER_UP 0xcd | ||
212 | #define BYD_PACKET_REGION_SCROLL_RIGHT 0x35 | ||
213 | #define BYD_PACKET_REGION_SCROLL_DOWN 0x36 | ||
214 | #define BYD_PACKET_REGION_SCROLL_UP 0xca | ||
215 | #define BYD_PACKET_REGION_SCROLL_LEFT 0xcb | ||
216 | #define BYD_PACKET_RIGHT_CORNER_CLICK 0xd2 | ||
217 | #define BYD_PACKET_LEFT_CORNER_CLICK 0x2e | ||
218 | #define BYD_PACKET_LEFT_AND_RIGHT_CORNER_CLICK 0x2f | ||
219 | #define BYD_PACKET_ONTO_PAD_SWIPE_RIGHT 0x37 | ||
220 | #define BYD_PACKET_ONTO_PAD_SWIPE_DOWN 0x30 | ||
221 | #define BYD_PACKET_ONTO_PAD_SWIPE_UP 0xd0 | ||
222 | #define BYD_PACKET_ONTO_PAD_SWIPE_LEFT 0xc9 | ||
223 | |||
224 | struct byd_data { | ||
225 | struct timer_list timer; | ||
226 | s32 abs_x; | ||
227 | s32 abs_y; | ||
228 | typeof(jiffies) last_touch_time; | ||
229 | bool btn_left; | ||
230 | bool btn_right; | ||
231 | bool touch; | ||
232 | }; | ||
233 | |||
234 | static void byd_report_input(struct psmouse *psmouse) | ||
56 | { | 235 | { |
57 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 236 | struct byd_data *priv = psmouse->private; |
58 | unsigned char param[4]; | 237 | struct input_dev *dev = psmouse->dev; |
59 | 238 | ||
60 | param[0] = 0x03; | 239 | input_report_key(dev, BTN_TOUCH, priv->touch); |
61 | param[1] = 0x00; | 240 | input_report_key(dev, BTN_TOOL_FINGER, priv->touch); |
62 | param[2] = 0x00; | ||
63 | param[3] = 0x00; | ||
64 | 241 | ||
65 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | 242 | input_report_abs(dev, ABS_X, priv->abs_x); |
66 | return -1; | 243 | input_report_abs(dev, ABS_Y, priv->abs_y); |
67 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | 244 | input_report_key(dev, BTN_LEFT, priv->btn_left); |
68 | return -1; | 245 | input_report_key(dev, BTN_RIGHT, priv->btn_right); |
69 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
70 | return -1; | ||
71 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
72 | return -1; | ||
73 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
74 | return -1; | ||
75 | 246 | ||
76 | if (param[1] != 0x03 || param[2] != 0x64) | 247 | input_sync(dev); |
77 | return -ENODEV; | 248 | } |
78 | 249 | ||
79 | psmouse_dbg(psmouse, "BYD touchpad detected\n"); | 250 | static void byd_clear_touch(unsigned long data) |
251 | { | ||
252 | struct psmouse *psmouse = (struct psmouse *)data; | ||
253 | struct byd_data *priv = psmouse->private; | ||
80 | 254 | ||
81 | if (set_properties) { | 255 | serio_pause_rx(psmouse->ps2dev.serio); |
82 | psmouse->vendor = "BYD"; | 256 | priv->touch = false; |
83 | psmouse->name = "TouchPad"; | ||
84 | } | ||
85 | 257 | ||
86 | return 0; | 258 | byd_report_input(psmouse); |
259 | |||
260 | serio_continue_rx(psmouse->ps2dev.serio); | ||
261 | |||
262 | /* | ||
263 | * Move cursor back to center of pad when we lose touch - this | ||
264 | * specifically improves user experience when moving cursor with one | ||
265 | * finger, and pressing a button with another. | ||
266 | */ | ||
267 | priv->abs_x = BYD_PAD_WIDTH / 2; | ||
268 | priv->abs_y = BYD_PAD_HEIGHT / 2; | ||
87 | } | 269 | } |
88 | 270 | ||
89 | static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) | 271 | static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) |
90 | { | 272 | { |
91 | struct input_dev *dev = psmouse->dev; | 273 | struct byd_data *priv = psmouse->private; |
92 | u8 *pkt = psmouse->packet; | 274 | u8 *pkt = psmouse->packet; |
93 | 275 | ||
94 | if (psmouse->pktcnt > 0 && !(pkt[0] & PS2_ALWAYS_1)) { | 276 | if (psmouse->pktcnt > 0 && !(pkt[0] & PS2_ALWAYS_1)) { |
@@ -102,53 +284,34 @@ static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) | |||
102 | 284 | ||
103 | /* Otherwise, a full packet has been received */ | 285 | /* Otherwise, a full packet has been received */ |
104 | switch (pkt[3]) { | 286 | switch (pkt[3]) { |
105 | case 0: { | 287 | case BYD_PACKET_ABSOLUTE: |
288 | /* Only use absolute packets for the start of movement. */ | ||
289 | if (!priv->touch) { | ||
290 | /* needed to detect tap */ | ||
291 | typeof(jiffies) tap_time = | ||
292 | priv->last_touch_time + BYD_TOUCH_TIMEOUT; | ||
293 | priv->touch = time_after(jiffies, tap_time); | ||
294 | |||
295 | /* init abs position */ | ||
296 | priv->abs_x = pkt[1] * (BYD_PAD_WIDTH / 256); | ||
297 | priv->abs_y = (255 - pkt[2]) * (BYD_PAD_HEIGHT / 256); | ||
298 | } | ||
299 | break; | ||
300 | case BYD_PACKET_RELATIVE: { | ||
106 | /* Standard packet */ | 301 | /* Standard packet */ |
107 | /* Sign-extend if a sign bit is set. */ | 302 | /* Sign-extend if a sign bit is set. */ |
108 | unsigned int signx = pkt[0] & PS2_X_SIGN ? ~0xFF : 0; | 303 | u32 signx = pkt[0] & PS2_X_SIGN ? ~0xFF : 0; |
109 | unsigned int signy = pkt[0] & PS2_Y_SIGN ? ~0xFF : 0; | 304 | u32 signy = pkt[0] & PS2_Y_SIGN ? ~0xFF : 0; |
110 | int dx = signx | (int) pkt[1]; | 305 | s32 dx = signx | (int) pkt[1]; |
111 | int dy = signy | (int) pkt[2]; | 306 | s32 dy = signy | (int) pkt[2]; |
112 | 307 | ||
113 | input_report_rel(psmouse->dev, REL_X, dx); | 308 | /* Update position based on velocity */ |
114 | input_report_rel(psmouse->dev, REL_Y, -dy); | 309 | priv->abs_x += dx * BYD_DT; |
310 | priv->abs_y -= dy * BYD_DT; | ||
115 | 311 | ||
116 | input_report_key(psmouse->dev, BTN_LEFT, pkt[0] & PS2_LEFT); | 312 | priv->touch = true; |
117 | input_report_key(psmouse->dev, BTN_RIGHT, pkt[0] & PS2_RIGHT); | ||
118 | input_report_key(psmouse->dev, BTN_MIDDLE, pkt[0] & PS2_MIDDLE); | ||
119 | break; | 313 | break; |
120 | } | 314 | } |
121 | |||
122 | case BYD_SCROLLDOWN: | ||
123 | case BYD_2DOWN: | ||
124 | input_report_rel(dev, REL_WHEEL, -1); | ||
125 | break; | ||
126 | |||
127 | case BYD_SCROLLUP: | ||
128 | case BYD_2UP: | ||
129 | input_report_rel(dev, REL_WHEEL, 1); | ||
130 | break; | ||
131 | |||
132 | case BYD_SCROLLLEFT: | ||
133 | case BYD_2LEFT: | ||
134 | input_report_rel(dev, REL_HWHEEL, -1); | ||
135 | break; | ||
136 | |||
137 | case BYD_SCROLLRIGHT: | ||
138 | case BYD_2RIGHT: | ||
139 | input_report_rel(dev, REL_HWHEEL, 1); | ||
140 | break; | ||
141 | |||
142 | case BYD_ZOOMOUT: | ||
143 | case BYD_ZOOMIN: | ||
144 | case BYD_3UP: | ||
145 | case BYD_3DOWN: | ||
146 | case BYD_3LEFT: | ||
147 | case BYD_3RIGHT: | ||
148 | case BYD_4UP: | ||
149 | case BYD_4DOWN: | ||
150 | break; | ||
151 | |||
152 | default: | 315 | default: |
153 | psmouse_warn(psmouse, | 316 | psmouse_warn(psmouse, |
154 | "Unrecognized Z: pkt = %02x %02x %02x %02x\n", | 317 | "Unrecognized Z: pkt = %02x %02x %02x %02x\n", |
@@ -157,134 +320,76 @@ static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) | |||
157 | return PSMOUSE_BAD_DATA; | 320 | return PSMOUSE_BAD_DATA; |
158 | } | 321 | } |
159 | 322 | ||
160 | input_sync(dev); | 323 | priv->btn_left = pkt[0] & PS2_LEFT; |
324 | priv->btn_right = pkt[0] & PS2_RIGHT; | ||
161 | 325 | ||
162 | return PSMOUSE_FULL_PACKET; | 326 | byd_report_input(psmouse); |
163 | } | ||
164 | 327 | ||
165 | /* Send a sequence of bytes, where each is ACKed before the next is sent. */ | 328 | /* Reset time since last touch. */ |
166 | static int byd_send_sequence(struct psmouse *psmouse, const u8 *seq, size_t len) | 329 | if (priv->touch) { |
167 | { | 330 | priv->last_touch_time = jiffies; |
168 | unsigned int i; | 331 | mod_timer(&priv->timer, jiffies + BYD_TOUCH_TIMEOUT); |
169 | |||
170 | for (i = 0; i < len; ++i) { | ||
171 | if (ps2_command(&psmouse->ps2dev, NULL, seq[i])) | ||
172 | return -1; | ||
173 | } | 332 | } |
174 | return 0; | ||
175 | } | ||
176 | |||
177 | /* Keep scrolling after fingers are removed. */ | ||
178 | #define SCROLL_INERTIAL 0x01 | ||
179 | #define SCROLL_NO_INERTIAL 0x02 | ||
180 | |||
181 | /* Clicking can be done by tapping or pressing. */ | ||
182 | #define CLICK_BOTH 0x01 | ||
183 | /* Clicking can only be done by pressing. */ | ||
184 | #define CLICK_PRESS_ONLY 0x02 | ||
185 | 333 | ||
186 | static int byd_enable(struct psmouse *psmouse) | 334 | return PSMOUSE_FULL_PACKET; |
187 | { | ||
188 | const u8 seq1[] = { 0xE2, 0x00, 0xE0, 0x02, 0xE0 }; | ||
189 | const u8 seq2[] = { | ||
190 | 0xD3, 0x01, | ||
191 | 0xD0, 0x00, | ||
192 | 0xD0, 0x04, | ||
193 | /* Whether clicking is done by tapping or pressing. */ | ||
194 | 0xD4, CLICK_PRESS_ONLY, | ||
195 | 0xD5, 0x01, | ||
196 | 0xD7, 0x03, | ||
197 | /* Vertical and horizontal one-finger scroll zone inertia. */ | ||
198 | 0xD8, SCROLL_INERTIAL, | ||
199 | 0xDA, 0x05, | ||
200 | 0xDB, 0x02, | ||
201 | 0xE4, 0x05, | ||
202 | 0xD6, 0x01, | ||
203 | 0xDE, 0x04, | ||
204 | 0xE3, 0x01, | ||
205 | 0xCF, 0x00, | ||
206 | 0xD2, 0x03, | ||
207 | /* Vertical and horizontal two-finger scrolling inertia. */ | ||
208 | 0xE5, SCROLL_INERTIAL, | ||
209 | 0xD9, 0x02, | ||
210 | 0xD9, 0x07, | ||
211 | 0xDC, 0x03, | ||
212 | 0xDD, 0x03, | ||
213 | 0xDF, 0x03, | ||
214 | 0xE1, 0x03, | ||
215 | 0xD1, 0x00, | ||
216 | 0xCE, 0x00, | ||
217 | 0xCC, 0x00, | ||
218 | 0xE0, 0x00, | ||
219 | 0xE2, 0x01 | ||
220 | }; | ||
221 | u8 param[4]; | ||
222 | |||
223 | if (byd_send_sequence(psmouse, seq1, ARRAY_SIZE(seq1))) | ||
224 | return -1; | ||
225 | |||
226 | /* Send a 0x01 command, which should return 4 bytes. */ | ||
227 | if (ps2_command(&psmouse->ps2dev, param, 0x0401)) | ||
228 | return -1; | ||
229 | |||
230 | if (byd_send_sequence(psmouse, seq2, ARRAY_SIZE(seq2))) | ||
231 | return -1; | ||
232 | |||
233 | return 0; | ||
234 | } | 335 | } |
235 | 336 | ||
236 | /* | 337 | static int byd_reset_touchpad(struct psmouse *psmouse) |
237 | * Send the set of PS/2 commands required to make it identify as an | ||
238 | * intellimouse with 4-byte instead of 3-byte packets. | ||
239 | */ | ||
240 | static int byd_send_intellimouse_sequence(struct psmouse *psmouse) | ||
241 | { | 338 | { |
242 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 339 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
243 | u8 param[4]; | 340 | u8 param[4]; |
244 | int i; | 341 | size_t i; |
342 | |||
245 | const struct { | 343 | const struct { |
246 | u16 command; | 344 | u16 command; |
247 | u8 arg; | 345 | u8 arg; |
248 | } seq[] = { | 346 | } seq[] = { |
249 | { PSMOUSE_CMD_RESET_BAT, 0 }, | 347 | /* |
250 | { PSMOUSE_CMD_RESET_BAT, 0 }, | 348 | * Intellimouse initialization sequence, to get 4-byte instead |
251 | { PSMOUSE_CMD_GETID, 0 }, | 349 | * of 3-byte packets. |
252 | { PSMOUSE_CMD_SETSCALE11, 0 }, | 350 | */ |
253 | { PSMOUSE_CMD_SETSCALE11, 0 }, | ||
254 | { PSMOUSE_CMD_SETSCALE11, 0 }, | ||
255 | { PSMOUSE_CMD_GETINFO, 0 }, | ||
256 | { PSMOUSE_CMD_SETRES, 0x03 }, | ||
257 | { PSMOUSE_CMD_SETRATE, 0xC8 }, | 351 | { PSMOUSE_CMD_SETRATE, 0xC8 }, |
258 | { PSMOUSE_CMD_SETRATE, 0x64 }, | 352 | { PSMOUSE_CMD_SETRATE, 0x64 }, |
259 | { PSMOUSE_CMD_SETRATE, 0x50 }, | 353 | { PSMOUSE_CMD_SETRATE, 0x50 }, |
260 | { PSMOUSE_CMD_GETID, 0 }, | 354 | { PSMOUSE_CMD_GETID, 0 }, |
261 | { PSMOUSE_CMD_SETRATE, 0xC8 }, | 355 | { PSMOUSE_CMD_ENABLE, 0 }, |
262 | { PSMOUSE_CMD_SETRATE, 0xC8 }, | 356 | /* |
263 | { PSMOUSE_CMD_SETRATE, 0x50 }, | 357 | * BYD-specific initialization, which enables absolute mode and |
264 | { PSMOUSE_CMD_GETID, 0 }, | 358 | * (if desired), the touchpad's built-in gesture detection. |
265 | { PSMOUSE_CMD_SETRATE, 0x64 }, | 359 | */ |
266 | { PSMOUSE_CMD_SETRES, 0x03 }, | 360 | { 0x10E2, 0x00 }, |
267 | { PSMOUSE_CMD_ENABLE, 0 } | 361 | { 0x10E0, 0x02 }, |
362 | /* The touchpad should reply with 4 seemingly-random bytes */ | ||
363 | { 0x14E0, 0x01 }, | ||
364 | /* Pairs of parameters and values. */ | ||
365 | { BYD_CMD_SET_HANDEDNESS, 0x01 }, | ||
366 | { BYD_CMD_SET_PHYSICAL_BUTTONS, 0x04 }, | ||
367 | { BYD_CMD_SET_TAP, 0x02 }, | ||
368 | { BYD_CMD_SET_ONE_FINGER_SCROLL, 0x04 }, | ||
369 | { BYD_CMD_SET_ONE_FINGER_SCROLL_FUNC, 0x04 }, | ||
370 | { BYD_CMD_SET_EDGE_MOTION, 0x01 }, | ||
371 | { BYD_CMD_SET_PALM_CHECK, 0x00 }, | ||
372 | { BYD_CMD_SET_MULTITOUCH, 0x02 }, | ||
373 | { BYD_CMD_SET_TWO_FINGER_SCROLL, 0x04 }, | ||
374 | { BYD_CMD_SET_TWO_FINGER_SCROLL_FUNC, 0x04 }, | ||
375 | { BYD_CMD_SET_LEFT_EDGE_REGION, 0x00 }, | ||
376 | { BYD_CMD_SET_TOP_EDGE_REGION, 0x00 }, | ||
377 | { BYD_CMD_SET_RIGHT_EDGE_REGION, 0x00 }, | ||
378 | { BYD_CMD_SET_BOTTOM_EDGE_REGION, 0x00 }, | ||
379 | { BYD_CMD_SET_ABSOLUTE_MODE, 0x02 }, | ||
380 | /* Finalize initialization. */ | ||
381 | { 0x10E0, 0x00 }, | ||
382 | { 0x10E2, 0x01 }, | ||
268 | }; | 383 | }; |
269 | 384 | ||
270 | memset(param, 0, sizeof(param)); | ||
271 | for (i = 0; i < ARRAY_SIZE(seq); ++i) { | 385 | for (i = 0; i < ARRAY_SIZE(seq); ++i) { |
386 | memset(param, 0, sizeof(param)); | ||
272 | param[0] = seq[i].arg; | 387 | param[0] = seq[i].arg; |
273 | if (ps2_command(ps2dev, param, seq[i].command)) | 388 | if (ps2_command(ps2dev, param, seq[i].command)) |
274 | return -1; | 389 | return -EIO; |
275 | } | 390 | } |
276 | 391 | ||
277 | return 0; | 392 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
278 | } | ||
279 | |||
280 | static int byd_reset_touchpad(struct psmouse *psmouse) | ||
281 | { | ||
282 | if (byd_send_intellimouse_sequence(psmouse)) | ||
283 | return -EIO; | ||
284 | |||
285 | if (byd_enable(psmouse)) | ||
286 | return -EIO; | ||
287 | |||
288 | return 0; | 393 | return 0; |
289 | } | 394 | } |
290 | 395 | ||
@@ -314,9 +419,50 @@ static int byd_reconnect(struct psmouse *psmouse) | |||
314 | return 0; | 419 | return 0; |
315 | } | 420 | } |
316 | 421 | ||
422 | static void byd_disconnect(struct psmouse *psmouse) | ||
423 | { | ||
424 | struct byd_data *priv = psmouse->private; | ||
425 | |||
426 | if (priv) { | ||
427 | del_timer(&priv->timer); | ||
428 | kfree(psmouse->private); | ||
429 | psmouse->private = NULL; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | int byd_detect(struct psmouse *psmouse, bool set_properties) | ||
434 | { | ||
435 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
436 | u8 param[4] = {0x03, 0x00, 0x00, 0x00}; | ||
437 | |||
438 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
439 | return -1; | ||
440 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
441 | return -1; | ||
442 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
443 | return -1; | ||
444 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
445 | return -1; | ||
446 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
447 | return -1; | ||
448 | |||
449 | if (param[1] != 0x03 || param[2] != 0x64) | ||
450 | return -ENODEV; | ||
451 | |||
452 | psmouse_dbg(psmouse, "BYD touchpad detected\n"); | ||
453 | |||
454 | if (set_properties) { | ||
455 | psmouse->vendor = "BYD"; | ||
456 | psmouse->name = "TouchPad"; | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
317 | int byd_init(struct psmouse *psmouse) | 462 | int byd_init(struct psmouse *psmouse) |
318 | { | 463 | { |
319 | struct input_dev *dev = psmouse->dev; | 464 | struct input_dev *dev = psmouse->dev; |
465 | struct byd_data *priv; | ||
320 | 466 | ||
321 | if (psmouse_reset(psmouse)) | 467 | if (psmouse_reset(psmouse)) |
322 | return -EIO; | 468 | return -EIO; |
@@ -324,14 +470,39 @@ int byd_init(struct psmouse *psmouse) | |||
324 | if (byd_reset_touchpad(psmouse)) | 470 | if (byd_reset_touchpad(psmouse)) |
325 | return -EIO; | 471 | return -EIO; |
326 | 472 | ||
473 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
474 | if (!priv) | ||
475 | return -ENOMEM; | ||
476 | |||
477 | memset(priv, 0, sizeof(*priv)); | ||
478 | setup_timer(&priv->timer, byd_clear_touch, (unsigned long) psmouse); | ||
479 | |||
480 | psmouse->private = priv; | ||
481 | psmouse->disconnect = byd_disconnect; | ||
327 | psmouse->reconnect = byd_reconnect; | 482 | psmouse->reconnect = byd_reconnect; |
328 | psmouse->protocol_handler = byd_process_byte; | 483 | psmouse->protocol_handler = byd_process_byte; |
329 | psmouse->pktsize = 4; | 484 | psmouse->pktsize = 4; |
330 | psmouse->resync_time = 0; | 485 | psmouse->resync_time = 0; |
331 | 486 | ||
332 | __set_bit(BTN_MIDDLE, dev->keybit); | 487 | __set_bit(INPUT_PROP_POINTER, dev->propbit); |
333 | __set_bit(REL_WHEEL, dev->relbit); | 488 | /* Touchpad */ |
334 | __set_bit(REL_HWHEEL, dev->relbit); | 489 | __set_bit(BTN_TOUCH, dev->keybit); |
490 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
491 | /* Buttons */ | ||
492 | __set_bit(BTN_LEFT, dev->keybit); | ||
493 | __set_bit(BTN_RIGHT, dev->keybit); | ||
494 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
495 | |||
496 | /* Absolute position */ | ||
497 | __set_bit(EV_ABS, dev->evbit); | ||
498 | input_set_abs_params(dev, ABS_X, 0, BYD_PAD_WIDTH, 0, 0); | ||
499 | input_set_abs_params(dev, ABS_Y, 0, BYD_PAD_HEIGHT, 0, 0); | ||
500 | input_abs_set_res(dev, ABS_X, BYD_PAD_RESOLUTION); | ||
501 | input_abs_set_res(dev, ABS_Y, BYD_PAD_RESOLUTION); | ||
502 | /* No relative support */ | ||
503 | __clear_bit(EV_REL, dev->evbit); | ||
504 | __clear_bit(REL_X, dev->relbit); | ||
505 | __clear_bit(REL_Y, dev->relbit); | ||
335 | 506 | ||
336 | return 0; | 507 | return 0; |
337 | } | 508 | } |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 39d1becd35c9..5784e20542a4 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -846,7 +846,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
846 | #ifdef CONFIG_MOUSE_PS2_BYD | 846 | #ifdef CONFIG_MOUSE_PS2_BYD |
847 | { | 847 | { |
848 | .type = PSMOUSE_BYD, | 848 | .type = PSMOUSE_BYD, |
849 | .name = "BydPS/2", | 849 | .name = "BYDPS/2", |
850 | .alias = "byd", | 850 | .alias = "byd", |
851 | .detect = byd_detect, | 851 | .detect = byd_detect, |
852 | .init = byd_init, | 852 | .init = byd_init, |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 6025eb430c0a..a41d8328c064 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -862,8 +862,9 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse, | |||
862 | if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) | 862 | if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) |
863 | return; | 863 | return; |
864 | 864 | ||
865 | /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */ | 865 | /* Bug in FW 8.1 & 8.2, buttons are reported only when ExtBit is 1 */ |
866 | if (SYN_ID_FULL(priv->identity) == 0x801 && | 866 | if ((SYN_ID_FULL(priv->identity) == 0x801 || |
867 | SYN_ID_FULL(priv->identity) == 0x802) && | ||
867 | !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) | 868 | !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) |
868 | return; | 869 | return; |
869 | 870 | ||
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index da38f0ad80ed..faa295ec4f31 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c | |||
@@ -126,7 +126,7 @@ static void process_one_interrupt(struct rmi_driver_data *data, | |||
126 | return; | 126 | return; |
127 | 127 | ||
128 | fh = to_rmi_function_handler(fn->dev.driver); | 128 | fh = to_rmi_function_handler(fn->dev.driver); |
129 | if (fn->irq_mask && fh->attention) { | 129 | if (fh->attention) { |
130 | bitmap_and(data->fn_irq_bits, data->irq_status, fn->irq_mask, | 130 | bitmap_and(data->fn_irq_bits, data->irq_status, fn->irq_mask, |
131 | data->irq_count); | 131 | data->irq_count); |
132 | if (!bitmap_empty(data->fn_irq_bits, data->irq_count)) | 132 | if (!bitmap_empty(data->fn_irq_bits, data->irq_count)) |
@@ -172,8 +172,7 @@ int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) | |||
172 | * use irq_chip. | 172 | * use irq_chip. |
173 | */ | 173 | */ |
174 | list_for_each_entry(entry, &data->function_list, node) | 174 | list_for_each_entry(entry, &data->function_list, node) |
175 | if (entry->irq_mask) | 175 | process_one_interrupt(data, entry); |
176 | process_one_interrupt(data, entry); | ||
177 | 176 | ||
178 | if (data->input) | 177 | if (data->input) |
179 | input_sync(data->input); | 178 | input_sync(data->input); |
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c index 892729734c51..fb5fb9140ca9 100644 --- a/drivers/input/touchscreen/melfas_mip4.c +++ b/drivers/input/touchscreen/melfas_mip4.c | |||
@@ -1310,8 +1310,34 @@ static ssize_t mip4_sysfs_read_fw_version(struct device *dev, | |||
1310 | 1310 | ||
1311 | static DEVICE_ATTR(fw_version, S_IRUGO, mip4_sysfs_read_fw_version, NULL); | 1311 | static DEVICE_ATTR(fw_version, S_IRUGO, mip4_sysfs_read_fw_version, NULL); |
1312 | 1312 | ||
1313 | static ssize_t mip4_sysfs_read_hw_version(struct device *dev, | ||
1314 | struct device_attribute *attr, | ||
1315 | char *buf) | ||
1316 | { | ||
1317 | struct i2c_client *client = to_i2c_client(dev); | ||
1318 | struct mip4_ts *ts = i2c_get_clientdata(client); | ||
1319 | size_t count; | ||
1320 | |||
1321 | /* Take lock to prevent racing with firmware update */ | ||
1322 | mutex_lock(&ts->input->mutex); | ||
1323 | |||
1324 | /* | ||
1325 | * product_name shows the name or version of the hardware | ||
1326 | * paired with current firmware in the chip. | ||
1327 | */ | ||
1328 | count = snprintf(buf, PAGE_SIZE, "%.*s\n", | ||
1329 | (int)sizeof(ts->product_name), ts->product_name); | ||
1330 | |||
1331 | mutex_unlock(&ts->input->mutex); | ||
1332 | |||
1333 | return count; | ||
1334 | } | ||
1335 | |||
1336 | static DEVICE_ATTR(hw_version, S_IRUGO, mip4_sysfs_read_hw_version, NULL); | ||
1337 | |||
1313 | static struct attribute *mip4_attrs[] = { | 1338 | static struct attribute *mip4_attrs[] = { |
1314 | &dev_attr_fw_version.attr, | 1339 | &dev_attr_fw_version.attr, |
1340 | &dev_attr_hw_version.attr, | ||
1315 | &dev_attr_update_fw.attr, | 1341 | &dev_attr_update_fw.attr, |
1316 | NULL, | 1342 | NULL, |
1317 | }; | 1343 | }; |
@@ -1512,6 +1538,6 @@ static struct i2c_driver mip4_driver = { | |||
1512 | module_i2c_driver(mip4_driver); | 1538 | module_i2c_driver(mip4_driver); |
1513 | 1539 | ||
1514 | MODULE_DESCRIPTION("MELFAS MIP4 Touchscreen"); | 1540 | MODULE_DESCRIPTION("MELFAS MIP4 Touchscreen"); |
1515 | MODULE_VERSION("2016.03.03"); | 1541 | MODULE_VERSION("2016.03.12"); |
1516 | MODULE_AUTHOR("Sangwon Jee <jeesw@melfas.com>"); | 1542 | MODULE_AUTHOR("Sangwon Jee <jeesw@melfas.com>"); |
1517 | MODULE_LICENSE("GPL"); | 1543 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index b6c4d03de340..880c40b23f66 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c | |||
@@ -197,28 +197,34 @@ static int sur40_command(struct sur40_state *dev, | |||
197 | static int sur40_init(struct sur40_state *dev) | 197 | static int sur40_init(struct sur40_state *dev) |
198 | { | 198 | { |
199 | int result; | 199 | int result; |
200 | u8 buffer[24]; | 200 | u8 *buffer; |
201 | |||
202 | buffer = kmalloc(24, GFP_KERNEL); | ||
203 | if (!buffer) { | ||
204 | result = -ENOMEM; | ||
205 | goto error; | ||
206 | } | ||
201 | 207 | ||
202 | /* stupidly replay the original MS driver init sequence */ | 208 | /* stupidly replay the original MS driver init sequence */ |
203 | result = sur40_command(dev, SUR40_GET_VERSION, 0x00, buffer, 12); | 209 | result = sur40_command(dev, SUR40_GET_VERSION, 0x00, buffer, 12); |
204 | if (result < 0) | 210 | if (result < 0) |
205 | return result; | 211 | goto error; |
206 | 212 | ||
207 | result = sur40_command(dev, SUR40_GET_VERSION, 0x01, buffer, 12); | 213 | result = sur40_command(dev, SUR40_GET_VERSION, 0x01, buffer, 12); |
208 | if (result < 0) | 214 | if (result < 0) |
209 | return result; | 215 | goto error; |
210 | 216 | ||
211 | result = sur40_command(dev, SUR40_GET_VERSION, 0x02, buffer, 12); | 217 | result = sur40_command(dev, SUR40_GET_VERSION, 0x02, buffer, 12); |
212 | if (result < 0) | 218 | if (result < 0) |
213 | return result; | 219 | goto error; |
214 | 220 | ||
215 | result = sur40_command(dev, SUR40_UNKNOWN2, 0x00, buffer, 24); | 221 | result = sur40_command(dev, SUR40_UNKNOWN2, 0x00, buffer, 24); |
216 | if (result < 0) | 222 | if (result < 0) |
217 | return result; | 223 | goto error; |
218 | 224 | ||
219 | result = sur40_command(dev, SUR40_UNKNOWN1, 0x00, buffer, 5); | 225 | result = sur40_command(dev, SUR40_UNKNOWN1, 0x00, buffer, 5); |
220 | if (result < 0) | 226 | if (result < 0) |
221 | return result; | 227 | goto error; |
222 | 228 | ||
223 | result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12); | 229 | result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12); |
224 | 230 | ||
@@ -226,7 +232,8 @@ static int sur40_init(struct sur40_state *dev) | |||
226 | * Discard the result buffer - no known data inside except | 232 | * Discard the result buffer - no known data inside except |
227 | * some version strings, maybe extract these sometime... | 233 | * some version strings, maybe extract these sometime... |
228 | */ | 234 | */ |
229 | 235 | error: | |
236 | kfree(buffer); | ||
230 | return result; | 237 | return result; |
231 | } | 238 | } |
232 | 239 | ||