diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-03-23 12:18:27 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-03-23 12:18:27 -0400 |
commit | 188933ac139a6f8ab06cad369bd0200af947b00d (patch) | |
tree | c4c107528fcf6b82e32a93b0596e13eea7aa9385 /drivers/input | |
parent | 4ed0e032c3cf27c6fabc154164d003c4e0ac4654 (diff) | |
parent | bc465aa9d045feb0e13b4a8f32cc33c1943f62d6 (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.c | 4 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/tc3589x-keypad.c | 6 | ||||
-rw-r--r-- | drivers/input/misc/mma8450.c | 1 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/cyapa_gen3.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/cyapa_gen5.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/focaltech.c | 50 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 14 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse.h | 6 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 212 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 28 | ||||
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 1 |
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 | ||
1400 | static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf) | 1400 | static 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 | |||
380 | void focaltech_set_resolution(struct psmouse *psmouse, unsigned int resolution) | ||
381 | { | ||
382 | /* not supported yet */ | ||
383 | } | ||
384 | |||
385 | static void focaltech_set_rate(struct psmouse *psmouse, unsigned int rate) | ||
386 | { | ||
387 | /* not supported yet */ | ||
388 | } | ||
389 | |||
390 | static void focaltech_set_scale(struct psmouse *psmouse, | ||
391 | enum psmouse_scale scale) | ||
392 | { | ||
393 | /* not supported yet */ | ||
394 | } | ||
395 | |||
384 | int focaltech_init(struct psmouse *psmouse) | 396 | int 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 | |||
460 | static 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 | ||
39 | enum psmouse_scale { | ||
40 | PSMOUSE_SCALE11, | ||
41 | PSMOUSE_SCALE21 | ||
42 | }; | ||
43 | |||
39 | struct psmouse { | 44 | struct 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 | ||
124 | static bool cr48_profile_sensor; | 121 | static bool cr48_profile_sensor; |
125 | 122 | ||
123 | #define ANY_BOARD_ID 0 | ||
126 | struct min_max_quirk { | 124 | struct 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 | ||
131 | static const struct min_max_quirk min_max_pnpid_table[] = { | 132 | static 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 | ||
249 | static 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 | */ |
249 | static int synaptics_board_id(struct psmouse *psmouse) | 266 | static 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 | |||
433 | static 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 | |||
404 | static int synaptics_query_hardware(struct psmouse *psmouse) | 463 | static 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 | ||
526 | static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet) | 587 | static 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 | ||
540 | static void synaptics_pt_activate(struct psmouse *psmouse) | 605 | static 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 | ||
680 | static 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 | |||
615 | static int synaptics_parse_hw_state(const unsigned char buf[], | 692 | static 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 | ||
840 | static 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 | |||
782 | static void synaptics_report_buttons(struct psmouse *psmouse, | 883 | static 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 | ||
804 | static void synaptics_report_mt_data(struct psmouse *psmouse, | 903 | static 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. |