aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-03-23 12:18:27 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-03-23 12:18:27 -0400
commit188933ac139a6f8ab06cad369bd0200af947b00d (patch)
treec4c107528fcf6b82e32a93b0596e13eea7aa9385 /drivers/input
parent4ed0e032c3cf27c6fabc154164d003c4e0ac4654 (diff)
parentbc465aa9d045feb0e13b4a8f32cc33c1943f62d6 (diff)
Merge tag 'v4.0-rc5' into next
Merge with the latest upstream to synchronize Synaptics changes and bring in new infrastructure pieces. Conflicts: drivers/input/mouse/synaptics.c
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/atkbd.c4
-rw-r--r--drivers/input/keyboard/gpio_keys.c2
-rw-r--r--drivers/input/keyboard/tc3589x-keypad.c6
-rw-r--r--drivers/input/misc/mma8450.c1
-rw-r--r--drivers/input/mouse/alps.c4
-rw-r--r--drivers/input/mouse/cyapa_gen3.c2
-rw-r--r--drivers/input/mouse/cyapa_gen5.c4
-rw-r--r--drivers/input/mouse/focaltech.c50
-rw-r--r--drivers/input/mouse/psmouse-base.c14
-rw-r--r--drivers/input/mouse/psmouse.h6
-rw-r--r--drivers/input/mouse/synaptics.c212
-rw-r--r--drivers/input/mouse/synaptics.h28
-rw-r--r--drivers/input/touchscreen/Kconfig1
13 files changed, 253 insertions, 81 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index e27a25892db4..387c51f4b4e4 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1399,8 +1399,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
1399 1399
1400static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf) 1400static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf)
1401{ 1401{
1402 size_t len = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, 1402 size_t len = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
1403 atkbd->force_release_mask, ATKBD_KEYMAP_SIZE); 1403 ATKBD_KEYMAP_SIZE, atkbd->force_release_mask);
1404 1404
1405 buf[len++] = '\n'; 1405 buf[len++] = '\n';
1406 buf[len] = '\0'; 1406 buf[len] = '\0';
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 883d6aed5b9a..ddf4045de084 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -190,7 +190,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
190 __set_bit(bdata->button->code, bits); 190 __set_bit(bdata->button->code, bits);
191 } 191 }
192 192
193 ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); 193 ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", n_events, bits);
194 buf[ret++] = '\n'; 194 buf[ret++] = '\n';
195 buf[ret] = '\0'; 195 buf[ret] = '\0';
196 196
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c
index 8ff612d160b0..563932500ff1 100644
--- a/drivers/input/keyboard/tc3589x-keypad.c
+++ b/drivers/input/keyboard/tc3589x-keypad.c
@@ -411,9 +411,9 @@ static int tc3589x_keypad_probe(struct platform_device *pdev)
411 411
412 input_set_drvdata(input, keypad); 412 input_set_drvdata(input, keypad);
413 413
414 error = request_threaded_irq(irq, NULL, 414 error = request_threaded_irq(irq, NULL, tc3589x_keypad_irq,
415 tc3589x_keypad_irq, plat->irqtype, 415 plat->irqtype | IRQF_ONESHOT,
416 "tc3589x-keypad", keypad); 416 "tc3589x-keypad", keypad);
417 if (error < 0) { 417 if (error < 0) {
418 dev_err(&pdev->dev, 418 dev_err(&pdev->dev,
419 "Could not allocate irq %d,error %d\n", 419 "Could not allocate irq %d,error %d\n",
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c
index 59d4dcddf6de..98228773a111 100644
--- a/drivers/input/misc/mma8450.c
+++ b/drivers/input/misc/mma8450.c
@@ -187,6 +187,7 @@ static int mma8450_probe(struct i2c_client *c,
187 idev->private = m; 187 idev->private = m;
188 idev->input->name = MMA8450_DRV_NAME; 188 idev->input->name = MMA8450_DRV_NAME;
189 idev->input->id.bustype = BUS_I2C; 189 idev->input->id.bustype = BUS_I2C;
190 idev->input->dev.parent = &c->dev;
190 idev->poll = mma8450_poll; 191 idev->poll = mma8450_poll;
191 idev->poll_interval = POLL_INTERVAL; 192 idev->poll_interval = POLL_INTERVAL;
192 idev->poll_interval_max = POLL_INTERVAL_MAX; 193 idev->poll_interval_max = POLL_INTERVAL_MAX;
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index d28726a0ef85..1bd15ebc01f2 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -2605,8 +2605,10 @@ int alps_detect(struct psmouse *psmouse, bool set_properties)
2605 return -ENOMEM; 2605 return -ENOMEM;
2606 2606
2607 error = alps_identify(psmouse, priv); 2607 error = alps_identify(psmouse, priv);
2608 if (error) 2608 if (error) {
2609 kfree(priv);
2609 return error; 2610 return error;
2611 }
2610 2612
2611 if (set_properties) { 2613 if (set_properties) {
2612 psmouse->vendor = "ALPS"; 2614 psmouse->vendor = "ALPS";
diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c
index 77e9d70a986b..1e2291c378fe 100644
--- a/drivers/input/mouse/cyapa_gen3.c
+++ b/drivers/input/mouse/cyapa_gen3.c
@@ -20,7 +20,7 @@
20#include <linux/input/mt.h> 20#include <linux/input/mt.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/unaligned/access_ok.h> 23#include <asm/unaligned.h>
24#include "cyapa.h" 24#include "cyapa.h"
25 25
26 26
diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c
index ddf5393a1180..5b611dd71e79 100644
--- a/drivers/input/mouse/cyapa_gen5.c
+++ b/drivers/input/mouse/cyapa_gen5.c
@@ -17,7 +17,7 @@
17#include <linux/mutex.h> 17#include <linux/mutex.h>
18#include <linux/completion.h> 18#include <linux/completion.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/unaligned/access_ok.h> 20#include <asm/unaligned.h>
21#include <linux/crc-itu-t.h> 21#include <linux/crc-itu-t.h>
22#include "cyapa.h" 22#include "cyapa.h"
23 23
@@ -1926,7 +1926,7 @@ static int cyapa_gen5_read_idac_data(struct cyapa *cyapa,
1926 electrodes_tx = cyapa->electrodes_x; 1926 electrodes_tx = cyapa->electrodes_x;
1927 max_element_cnt = ((cyapa->aligned_electrodes_rx + 7) & 1927 max_element_cnt = ((cyapa->aligned_electrodes_rx + 7) &
1928 ~7u) * electrodes_tx; 1928 ~7u) * electrodes_tx;
1929 } else if (idac_data_type == GEN5_RETRIEVE_SELF_CAP_PWC_DATA) { 1929 } else {
1930 offset = 2; 1930 offset = 2;
1931 max_element_cnt = cyapa->electrodes_x + 1931 max_element_cnt = cyapa->electrodes_x +
1932 cyapa->electrodes_y; 1932 cyapa->electrodes_y;
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
index 757f78a94aec..23d259416f2f 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -67,9 +67,6 @@ static void focaltech_reset(struct psmouse *psmouse)
67 67
68#define FOC_MAX_FINGERS 5 68#define FOC_MAX_FINGERS 5
69 69
70#define FOC_MAX_X 2431
71#define FOC_MAX_Y 1663
72
73/* 70/*
74 * Current state of a single finger on the touchpad. 71 * Current state of a single finger on the touchpad.
75 */ 72 */
@@ -129,9 +126,17 @@ static void focaltech_report_state(struct psmouse *psmouse)
129 input_mt_slot(dev, i); 126 input_mt_slot(dev, i);
130 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); 127 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
131 if (active) { 128 if (active) {
132 input_report_abs(dev, ABS_MT_POSITION_X, finger->x); 129 unsigned int clamped_x, clamped_y;
130 /*
131 * The touchpad might report invalid data, so we clamp
132 * the resulting values so that we do not confuse
133 * userspace.
134 */
135 clamped_x = clamp(finger->x, 0U, priv->x_max);
136 clamped_y = clamp(finger->y, 0U, priv->y_max);
137 input_report_abs(dev, ABS_MT_POSITION_X, clamped_x);
133 input_report_abs(dev, ABS_MT_POSITION_Y, 138 input_report_abs(dev, ABS_MT_POSITION_Y,
134 FOC_MAX_Y - finger->y); 139 priv->y_max - clamped_y);
135 } 140 }
136 } 141 }
137 input_mt_report_pointer_emulation(dev, true); 142 input_mt_report_pointer_emulation(dev, true);
@@ -180,16 +185,6 @@ static void focaltech_process_abs_packet(struct psmouse *psmouse,
180 185
181 state->pressed = (packet[0] >> 4) & 1; 186 state->pressed = (packet[0] >> 4) & 1;
182 187
183 /*
184 * packet[5] contains some kind of tool size in the most
185 * significant nibble. 0xff is a special value (latching) that
186 * signals a large contact area.
187 */
188 if (packet[5] == 0xff) {
189 state->fingers[finger].valid = false;
190 return;
191 }
192
193 state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2]; 188 state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
194 state->fingers[finger].y = (packet[3] << 8) | packet[4]; 189 state->fingers[finger].y = (packet[3] << 8) | packet[4];
195 state->fingers[finger].valid = true; 190 state->fingers[finger].valid = true;
@@ -381,6 +376,23 @@ static int focaltech_read_size(struct psmouse *psmouse)
381 376
382 return 0; 377 return 0;
383} 378}
379
380void focaltech_set_resolution(struct psmouse *psmouse, unsigned int resolution)
381{
382 /* not supported yet */
383}
384
385static void focaltech_set_rate(struct psmouse *psmouse, unsigned int rate)
386{
387 /* not supported yet */
388}
389
390static void focaltech_set_scale(struct psmouse *psmouse,
391 enum psmouse_scale scale)
392{
393 /* not supported yet */
394}
395
384int focaltech_init(struct psmouse *psmouse) 396int focaltech_init(struct psmouse *psmouse)
385{ 397{
386 struct focaltech_data *priv; 398 struct focaltech_data *priv;
@@ -415,6 +427,14 @@ int focaltech_init(struct psmouse *psmouse)
415 psmouse->cleanup = focaltech_reset; 427 psmouse->cleanup = focaltech_reset;
416 /* resync is not supported yet */ 428 /* resync is not supported yet */
417 psmouse->resync_time = 0; 429 psmouse->resync_time = 0;
430 /*
431 * rate/resolution/scale changes are not supported yet, and
432 * the generic implementations of these functions seem to
433 * confuse some touchpads
434 */
435 psmouse->set_resolution = focaltech_set_resolution;
436 psmouse->set_rate = focaltech_set_rate;
437 psmouse->set_scale = focaltech_set_scale;
418 438
419 return 0; 439 return 0;
420 440
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index bd91a8efa0f1..27057df7ba74 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -454,6 +454,17 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
454} 454}
455 455
456/* 456/*
457 * Here we set the mouse scaling.
458 */
459
460static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale)
461{
462 ps2_command(&psmouse->ps2dev, NULL,
463 scale == PSMOUSE_SCALE21 ? PSMOUSE_CMD_SETSCALE21 :
464 PSMOUSE_CMD_SETSCALE11);
465}
466
467/*
457 * psmouse_poll() - default poll handler. Everyone except for ALPS uses it. 468 * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
458 */ 469 */
459 470
@@ -715,6 +726,7 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
715 726
716 psmouse->set_rate = psmouse_set_rate; 727 psmouse->set_rate = psmouse_set_rate;
717 psmouse->set_resolution = psmouse_set_resolution; 728 psmouse->set_resolution = psmouse_set_resolution;
729 psmouse->set_scale = psmouse_set_scale;
718 psmouse->poll = psmouse_poll; 730 psmouse->poll = psmouse_poll;
719 psmouse->protocol_handler = psmouse_process_byte; 731 psmouse->protocol_handler = psmouse_process_byte;
720 psmouse->pktsize = 3; 732 psmouse->pktsize = 3;
@@ -1186,7 +1198,7 @@ static void psmouse_initialize(struct psmouse *psmouse)
1186 if (psmouse_max_proto != PSMOUSE_PS2) { 1198 if (psmouse_max_proto != PSMOUSE_PS2) {
1187 psmouse->set_rate(psmouse, psmouse->rate); 1199 psmouse->set_rate(psmouse, psmouse->rate);
1188 psmouse->set_resolution(psmouse, psmouse->resolution); 1200 psmouse->set_resolution(psmouse, psmouse->resolution);
1189 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); 1201 psmouse->set_scale(psmouse, PSMOUSE_SCALE11);
1190 } 1202 }
1191} 1203}
1192 1204
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index c2ff137ecbdb..d02e1bdc9ae4 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -36,6 +36,11 @@ typedef enum {
36 PSMOUSE_FULL_PACKET 36 PSMOUSE_FULL_PACKET
37} psmouse_ret_t; 37} psmouse_ret_t;
38 38
39enum psmouse_scale {
40 PSMOUSE_SCALE11,
41 PSMOUSE_SCALE21
42};
43
39struct psmouse { 44struct psmouse {
40 void *private; 45 void *private;
41 struct input_dev *dev; 46 struct input_dev *dev;
@@ -67,6 +72,7 @@ struct psmouse {
67 psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); 72 psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
68 void (*set_rate)(struct psmouse *psmouse, unsigned int rate); 73 void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
69 void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution); 74 void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution);
75 void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale);
70 76
71 int (*reconnect)(struct psmouse *psmouse); 77 int (*reconnect)(struct psmouse *psmouse);
72 void (*disconnect)(struct psmouse *psmouse); 78 void (*disconnect)(struct psmouse *psmouse);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 4c69e3304011..d73a94270211 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -67,9 +67,6 @@
67#define X_MAX_POSITIVE 8176 67#define X_MAX_POSITIVE 8176
68#define Y_MAX_POSITIVE 8176 68#define Y_MAX_POSITIVE 8176
69 69
70/* maximum ABS_MT_POSITION displacement (in mm) */
71#define DMAX 10
72
73/***************************************************************************** 70/*****************************************************************************
74 * Stuff we need even when we do not want native Synaptics support 71 * Stuff we need even when we do not want native Synaptics support
75 ****************************************************************************/ 72 ****************************************************************************/
@@ -123,32 +120,41 @@ void synaptics_reset(struct psmouse *psmouse)
123 120
124static bool cr48_profile_sensor; 121static bool cr48_profile_sensor;
125 122
123#define ANY_BOARD_ID 0
126struct min_max_quirk { 124struct min_max_quirk {
127 const char * const *pnp_ids; 125 const char * const *pnp_ids;
126 struct {
127 unsigned long int min, max;
128 } board_id;
128 int x_min, x_max, y_min, y_max; 129 int x_min, x_max, y_min, y_max;
129}; 130};
130 131
131static const struct min_max_quirk min_max_pnpid_table[] = { 132static const struct min_max_quirk min_max_pnpid_table[] = {
132 { 133 {
133 (const char * const []){"LEN0033", NULL}, 134 (const char * const []){"LEN0033", NULL},
135 {ANY_BOARD_ID, ANY_BOARD_ID},
134 1024, 5052, 2258, 4832 136 1024, 5052, 2258, 4832
135 }, 137 },
136 { 138 {
137 (const char * const []){"LEN0035", "LEN0042", NULL}, 139 (const char * const []){"LEN0042", NULL},
140 {ANY_BOARD_ID, ANY_BOARD_ID},
138 1232, 5710, 1156, 4696 141 1232, 5710, 1156, 4696
139 }, 142 },
140 { 143 {
141 (const char * const []){"LEN0034", "LEN0036", "LEN0037", 144 (const char * const []){"LEN0034", "LEN0036", "LEN0037",
142 "LEN0039", "LEN2002", "LEN2004", 145 "LEN0039", "LEN2002", "LEN2004",
143 NULL}, 146 NULL},
147 {ANY_BOARD_ID, 2961},
144 1024, 5112, 2024, 4832 148 1024, 5112, 2024, 4832
145 }, 149 },
146 { 150 {
147 (const char * const []){"LEN2001", NULL}, 151 (const char * const []){"LEN2001", NULL},
152 {ANY_BOARD_ID, ANY_BOARD_ID},
148 1024, 5022, 2508, 4832 153 1024, 5022, 2508, 4832
149 }, 154 },
150 { 155 {
151 (const char * const []){"LEN2006", NULL}, 156 (const char * const []){"LEN2006", NULL},
157 {ANY_BOARD_ID, ANY_BOARD_ID},
152 1264, 5675, 1171, 4688 158 1264, 5675, 1171, 4688
153 }, 159 },
154 { } 160 { }
@@ -175,9 +181,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
175 "LEN0041", 181 "LEN0041",
176 "LEN0042", /* Yoga */ 182 "LEN0042", /* Yoga */
177 "LEN0045", 183 "LEN0045",
178 "LEN0046",
179 "LEN0047", 184 "LEN0047",
180 "LEN0048",
181 "LEN0049", 185 "LEN0049",
182 "LEN2000", 186 "LEN2000",
183 "LEN2001", /* Edge E431 */ 187 "LEN2001", /* Edge E431 */
@@ -242,18 +246,39 @@ static int synaptics_model_id(struct psmouse *psmouse)
242 return 0; 246 return 0;
243} 247}
244 248
249static int synaptics_more_extended_queries(struct psmouse *psmouse)
250{
251 struct synaptics_data *priv = psmouse->private;
252 unsigned char buf[3];
253
254 if (synaptics_send_cmd(psmouse, SYN_QUE_MEXT_CAPAB_10, buf))
255 return -1;
256
257 priv->ext_cap_10 = (buf[0]<<16) | (buf[1]<<8) | buf[2];
258
259 return 0;
260}
261
245/* 262/*
246 * Read the board id from the touchpad 263 * Read the board id and the "More Extended Queries" from the touchpad
247 * The board id is encoded in the "QUERY MODES" response 264 * The board id is encoded in the "QUERY MODES" response
248 */ 265 */
249static int synaptics_board_id(struct psmouse *psmouse) 266static int synaptics_query_modes(struct psmouse *psmouse)
250{ 267{
251 struct synaptics_data *priv = psmouse->private; 268 struct synaptics_data *priv = psmouse->private;
252 unsigned char bid[3]; 269 unsigned char bid[3];
253 270
271 /* firmwares prior 7.5 have no board_id encoded */
272 if (SYN_ID_FULL(priv->identity) < 0x705)
273 return 0;
274
254 if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) 275 if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid))
255 return -1; 276 return -1;
256 priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; 277 priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1];
278
279 if (SYN_MEXT_CAP_BIT(bid[0]))
280 return synaptics_more_extended_queries(psmouse);
281
257 return 0; 282 return 0;
258} 283}
259 284
@@ -353,7 +378,6 @@ static int synaptics_resolution(struct psmouse *psmouse)
353{ 378{
354 struct synaptics_data *priv = psmouse->private; 379 struct synaptics_data *priv = psmouse->private;
355 unsigned char resp[3]; 380 unsigned char resp[3];
356 int i;
357 381
358 if (SYN_ID_MAJOR(priv->identity) < 4) 382 if (SYN_ID_MAJOR(priv->identity) < 4)
359 return 0; 383 return 0;
@@ -365,17 +389,6 @@ static int synaptics_resolution(struct psmouse *psmouse)
365 } 389 }
366 } 390 }
367 391
368 for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) {
369 if (psmouse_matches_pnp_id(psmouse,
370 min_max_pnpid_table[i].pnp_ids)) {
371 priv->x_min = min_max_pnpid_table[i].x_min;
372 priv->x_max = min_max_pnpid_table[i].x_max;
373 priv->y_min = min_max_pnpid_table[i].y_min;
374 priv->y_max = min_max_pnpid_table[i].y_max;
375 return 0;
376 }
377 }
378
379 if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && 392 if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 &&
380 SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { 393 SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) {
381 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { 394 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) {
@@ -384,23 +397,69 @@ static int synaptics_resolution(struct psmouse *psmouse)
384 } else { 397 } else {
385 priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); 398 priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
386 priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); 399 priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
400 psmouse_info(psmouse,
401 "queried max coordinates: x [..%d], y [..%d]\n",
402 priv->x_max, priv->y_max);
387 } 403 }
388 } 404 }
389 405
390 if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && 406 if (SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c) &&
391 SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { 407 (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 ||
408 /*
409 * Firmware v8.1 does not report proper number of extended
410 * capabilities, but has been proven to report correct min
411 * coordinates.
412 */
413 SYN_ID_FULL(priv->identity) == 0x801)) {
392 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { 414 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) {
393 psmouse_warn(psmouse, 415 psmouse_warn(psmouse,
394 "device claims to have min coordinates query, but I'm not able to read it.\n"); 416 "device claims to have min coordinates query, but I'm not able to read it.\n");
395 } else { 417 } else {
396 priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); 418 priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
397 priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); 419 priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
420 psmouse_info(psmouse,
421 "queried min coordinates: x [%d..], y [%d..]\n",
422 priv->x_min, priv->y_min);
398 } 423 }
399 } 424 }
400 425
401 return 0; 426 return 0;
402} 427}
403 428
429/*
430 * Apply quirk(s) if the hardware matches
431 */
432
433static void synaptics_apply_quirks(struct psmouse *psmouse)
434{
435 struct synaptics_data *priv = psmouse->private;
436 int i;
437
438 for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) {
439 if (!psmouse_matches_pnp_id(psmouse,
440 min_max_pnpid_table[i].pnp_ids))
441 continue;
442
443 if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID &&
444 priv->board_id < min_max_pnpid_table[i].board_id.min)
445 continue;
446
447 if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID &&
448 priv->board_id > min_max_pnpid_table[i].board_id.max)
449 continue;
450
451 priv->x_min = min_max_pnpid_table[i].x_min;
452 priv->x_max = min_max_pnpid_table[i].x_max;
453 priv->y_min = min_max_pnpid_table[i].y_min;
454 priv->y_max = min_max_pnpid_table[i].y_max;
455 psmouse_info(psmouse,
456 "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n",
457 priv->x_min, priv->x_max,
458 priv->y_min, priv->y_max);
459 break;
460 }
461}
462
404static int synaptics_query_hardware(struct psmouse *psmouse) 463static int synaptics_query_hardware(struct psmouse *psmouse)
405{ 464{
406 if (synaptics_identify(psmouse)) 465 if (synaptics_identify(psmouse))
@@ -409,13 +468,15 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
409 return -1; 468 return -1;
410 if (synaptics_firmware_id(psmouse)) 469 if (synaptics_firmware_id(psmouse))
411 return -1; 470 return -1;
412 if (synaptics_board_id(psmouse)) 471 if (synaptics_query_modes(psmouse))
413 return -1; 472 return -1;
414 if (synaptics_capability(psmouse)) 473 if (synaptics_capability(psmouse))
415 return -1; 474 return -1;
416 if (synaptics_resolution(psmouse)) 475 if (synaptics_resolution(psmouse))
417 return -1; 476 return -1;
418 477
478 synaptics_apply_quirks(psmouse);
479
419 return 0; 480 return 0;
420} 481}
421 482
@@ -523,18 +584,22 @@ static int synaptics_is_pt_packet(unsigned char *buf)
523 return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; 584 return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
524} 585}
525 586
526static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet) 587static void synaptics_pass_pt_packet(struct psmouse *psmouse,
588 struct serio *ptport,
589 unsigned char *packet)
527{ 590{
591 struct synaptics_data *priv = psmouse->private;
528 struct psmouse *child = serio_get_drvdata(ptport); 592 struct psmouse *child = serio_get_drvdata(ptport);
529 593
530 if (child && child->state == PSMOUSE_ACTIVATED) { 594 if (child && child->state == PSMOUSE_ACTIVATED) {
531 serio_interrupt(ptport, packet[1], 0); 595 serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0);
532 serio_interrupt(ptport, packet[4], 0); 596 serio_interrupt(ptport, packet[4], 0);
533 serio_interrupt(ptport, packet[5], 0); 597 serio_interrupt(ptport, packet[5], 0);
534 if (child->pktsize == 4) 598 if (child->pktsize == 4)
535 serio_interrupt(ptport, packet[2], 0); 599 serio_interrupt(ptport, packet[2], 0);
536 } else 600 } else {
537 serio_interrupt(ptport, packet[1], 0); 601 serio_interrupt(ptport, packet[1], 0);
602 }
538} 603}
539 604
540static void synaptics_pt_activate(struct psmouse *psmouse) 605static void synaptics_pt_activate(struct psmouse *psmouse)
@@ -612,6 +677,18 @@ static void synaptics_parse_agm(const unsigned char buf[],
612 } 677 }
613} 678}
614 679
680static void synaptics_parse_ext_buttons(const unsigned char buf[],
681 struct synaptics_data *priv,
682 struct synaptics_hw_state *hw)
683{
684 unsigned int ext_bits =
685 (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1;
686 unsigned int ext_mask = GENMASK(ext_bits - 1, 0);
687
688 hw->ext_buttons = buf[4] & ext_mask;
689 hw->ext_buttons |= (buf[5] & ext_mask) << ext_bits;
690}
691
615static int synaptics_parse_hw_state(const unsigned char buf[], 692static int synaptics_parse_hw_state(const unsigned char buf[],
616 struct synaptics_data *priv, 693 struct synaptics_data *priv,
617 struct synaptics_hw_state *hw) 694 struct synaptics_hw_state *hw)
@@ -696,28 +773,9 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
696 hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; 773 hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
697 } 774 }
698 775
699 if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && 776 if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 0 &&
700 ((buf[0] ^ buf[3]) & 0x02)) { 777 ((buf[0] ^ buf[3]) & 0x02)) {
701 switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { 778 synaptics_parse_ext_buttons(buf, priv, hw);
702 default:
703 /*
704 * if nExtBtn is greater than 8 it should be
705 * considered invalid and treated as 0
706 */
707 break;
708 case 8:
709 hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0;
710 hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0;
711 case 6:
712 hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0;
713 hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0;
714 case 4:
715 hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0;
716 hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0;
717 case 2:
718 hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0;
719 hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0;
720 }
721 } 779 }
722 } else { 780 } else {
723 hw->x = (((buf[1] & 0x1f) << 8) | buf[2]); 781 hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
@@ -779,12 +837,54 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev,
779 } 837 }
780} 838}
781 839
840static void synaptics_report_ext_buttons(struct psmouse *psmouse,
841 const struct synaptics_hw_state *hw)
842{
843 struct input_dev *dev = psmouse->dev;
844 struct synaptics_data *priv = psmouse->private;
845 int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1;
846 char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
847 int i;
848
849 if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
850 return;
851
852 /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */
853 if (SYN_ID_FULL(priv->identity) == 0x801 &&
854 !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02))
855 return;
856
857 if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) {
858 for (i = 0; i < ext_bits; i++) {
859 input_report_key(dev, BTN_0 + 2 * i,
860 hw->ext_buttons & (1 << i));
861 input_report_key(dev, BTN_1 + 2 * i,
862 hw->ext_buttons & (1 << (i + ext_bits)));
863 }
864 return;
865 }
866
867 /*
868 * This generation of touchpads has the trackstick buttons
869 * physically wired to the touchpad. Re-route them through
870 * the pass-through interface.
871 */
872 if (!priv->pt_port)
873 return;
874
875 /* The trackstick expects at most 3 buttons */
876 priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) |
877 SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 |
878 SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2;
879
880 synaptics_pass_pt_packet(psmouse, priv->pt_port, buf);
881}
882
782static void synaptics_report_buttons(struct psmouse *psmouse, 883static void synaptics_report_buttons(struct psmouse *psmouse,
783 const struct synaptics_hw_state *hw) 884 const struct synaptics_hw_state *hw)
784{ 885{
785 struct input_dev *dev = psmouse->dev; 886 struct input_dev *dev = psmouse->dev;
786 struct synaptics_data *priv = psmouse->private; 887 struct synaptics_data *priv = psmouse->private;
787 int i;
788 888
789 input_report_key(dev, BTN_LEFT, hw->left); 889 input_report_key(dev, BTN_LEFT, hw->left);
790 input_report_key(dev, BTN_RIGHT, hw->right); 890 input_report_key(dev, BTN_RIGHT, hw->right);
@@ -797,8 +897,7 @@ static void synaptics_report_buttons(struct psmouse *psmouse,
797 input_report_key(dev, BTN_BACK, hw->down); 897 input_report_key(dev, BTN_BACK, hw->down);
798 } 898 }
799 899
800 for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) 900 synaptics_report_ext_buttons(psmouse, hw);
801 input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i));
802} 901}
803 902
804static void synaptics_report_mt_data(struct psmouse *psmouse, 903static void synaptics_report_mt_data(struct psmouse *psmouse,
@@ -818,7 +917,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse,
818 pos[i].y = synaptics_invert_y(hw[i]->y); 917 pos[i].y = synaptics_invert_y(hw[i]->y);
819 } 918 }
820 919
821 input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->x_res); 920 input_mt_assign_slots(dev, slot, pos, nsemi, 0);
822 921
823 for (i = 0; i < nsemi; i++) { 922 for (i = 0; i < nsemi; i++) {
824 input_mt_slot(dev, slot[i]); 923 input_mt_slot(dev, slot[i]);
@@ -1019,7 +1118,8 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
1019 if (SYN_CAP_PASS_THROUGH(priv->capabilities) && 1118 if (SYN_CAP_PASS_THROUGH(priv->capabilities) &&
1020 synaptics_is_pt_packet(psmouse->packet)) { 1119 synaptics_is_pt_packet(psmouse->packet)) {
1021 if (priv->pt_port) 1120 if (priv->pt_port)
1022 synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); 1121 synaptics_pass_pt_packet(psmouse, priv->pt_port,
1122 psmouse->packet);
1023 } else 1123 } else
1024 synaptics_process_packet(psmouse); 1124 synaptics_process_packet(psmouse);
1025 1125
@@ -1121,8 +1221,9 @@ static void set_input_params(struct psmouse *psmouse,
1121 __set_bit(BTN_BACK, dev->keybit); 1221 __set_bit(BTN_BACK, dev->keybit);
1122 } 1222 }
1123 1223
1124 for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) 1224 if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10))
1125 __set_bit(BTN_0 + i, dev->keybit); 1225 for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
1226 __set_bit(BTN_0 + i, dev->keybit);
1126 1227
1127 __clear_bit(EV_REL, dev->evbit); 1228 __clear_bit(EV_REL, dev->evbit);
1128 __clear_bit(REL_X, dev->relbit); 1229 __clear_bit(REL_X, dev->relbit);
@@ -1130,7 +1231,8 @@ static void set_input_params(struct psmouse *psmouse,
1130 1231
1131 if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { 1232 if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
1132 __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); 1233 __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
1133 if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids)) 1234 if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
1235 !SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10))
1134 __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit); 1236 __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
1135 /* Clickpads report only left button */ 1237 /* Clickpads report only left button */
1136 __clear_bit(BTN_RIGHT, dev->keybit); 1238 __clear_bit(BTN_RIGHT, dev->keybit);
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index fb3838ca28de..56faa7ec4434 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -22,6 +22,7 @@
22#define SYN_QUE_EXT_CAPAB_0C 0x0c 22#define SYN_QUE_EXT_CAPAB_0C 0x0c
23#define SYN_QUE_EXT_MAX_COORDS 0x0d 23#define SYN_QUE_EXT_MAX_COORDS 0x0d
24#define SYN_QUE_EXT_MIN_COORDS 0x0f 24#define SYN_QUE_EXT_MIN_COORDS 0x0f
25#define SYN_QUE_MEXT_CAPAB_10 0x10
25 26
26/* synatics modes */ 27/* synatics modes */
27#define SYN_BIT_ABSOLUTE_MODE (1 << 7) 28#define SYN_BIT_ABSOLUTE_MODE (1 << 7)
@@ -53,6 +54,7 @@
53#define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) 54#define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20)
54#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) 55#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
55#define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) 56#define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16)
57#define SYN_MEXT_CAP_BIT(m) ((m) & (1 << 1))
56 58
57/* 59/*
58 * The following describes response for the 0x0c query. 60 * The following describes response for the 0x0c query.
@@ -89,6 +91,30 @@
89#define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) 91#define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400)
90#define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) 92#define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800)
91 93
94/*
95 * The following descibes response for the 0x10 query.
96 *
97 * byte mask name meaning
98 * ---- ---- ------- ------------
99 * 1 0x01 ext buttons are stick buttons exported in the extended
100 * capability are actually meant to be used
101 * by the tracktick (pass-through).
102 * 1 0x02 SecurePad the touchpad is a SecurePad, so it
103 * contains a built-in fingerprint reader.
104 * 1 0xe0 more ext count how many more extented queries are
105 * available after this one.
106 * 2 0xff SecurePad width the width of the SecurePad fingerprint
107 * reader.
108 * 3 0xff SecurePad height the height of the SecurePad fingerprint
109 * reader.
110 */
111#define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & 0x010000)
112#define SYN_CAP_SECUREPAD(ex10) ((ex10) & 0x020000)
113
114#define SYN_CAP_EXT_BUTTON_STICK_L(eb) (!!((eb) & 0x01))
115#define SYN_CAP_EXT_BUTTON_STICK_M(eb) (!!((eb) & 0x02))
116#define SYN_CAP_EXT_BUTTON_STICK_R(eb) (!!((eb) & 0x04))
117
92/* synaptics modes query bits */ 118/* synaptics modes query bits */
93#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) 119#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
94#define SYN_MODE_RATE(m) ((m) & (1 << 6)) 120#define SYN_MODE_RATE(m) ((m) & (1 << 6))
@@ -143,6 +169,7 @@ struct synaptics_data {
143 unsigned long int capabilities; /* Capabilities */ 169 unsigned long int capabilities; /* Capabilities */
144 unsigned long int ext_cap; /* Extended Capabilities */ 170 unsigned long int ext_cap; /* Extended Capabilities */
145 unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ 171 unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */
172 unsigned long int ext_cap_10; /* Ext Caps from 0x10 query */
146 unsigned long int identity; /* Identification */ 173 unsigned long int identity; /* Identification */
147 unsigned int x_res, y_res; /* X/Y resolution in units/mm */ 174 unsigned int x_res, y_res; /* X/Y resolution in units/mm */
148 unsigned int x_max, y_max; /* Max coordinates (from FW) */ 175 unsigned int x_max, y_max; /* Max coordinates (from FW) */
@@ -156,6 +183,7 @@ struct synaptics_data {
156 bool disable_gesture; /* disable gestures */ 183 bool disable_gesture; /* disable gestures */
157 184
158 struct serio *pt_port; /* Pass-through serio port */ 185 struct serio *pt_port; /* Pass-through serio port */
186 unsigned char pt_buttons; /* Pass-through buttons */
159 187
160 /* 188 /*
161 * Last received Advanced Gesture Mode (AGM) packet. An AGM packet 189 * Last received Advanced Gesture Mode (AGM) packet. An AGM packet
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 2310d863a6f1..1130c4059104 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -944,6 +944,7 @@ config TOUCHSCREEN_SUN4I
944 tristate "Allwinner sun4i resistive touchscreen controller support" 944 tristate "Allwinner sun4i resistive touchscreen controller support"
945 depends on ARCH_SUNXI || COMPILE_TEST 945 depends on ARCH_SUNXI || COMPILE_TEST
946 depends on HWMON 946 depends on HWMON
947 depends on THERMAL || !THERMAL_OF
947 help 948 help
948 This selects support for the resistive touchscreen controller 949 This selects support for the resistive touchscreen controller
949 found on Allwinner sunxi SoCs. 950 found on Allwinner sunxi SoCs.