Commit dbe08116 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input fixes from Dmitry Torokhov:
 "The main change is support for keyboards and touchpads found in 2015
  editions of Macbooks"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Revert "Input: zforce - don't overwrite the stack"
  Input: bcm5974 - add support for the 2015 Macbook Pro
  HID: apple: Add support for the 2015 Macbook Pro
  Input: bcm5974 - prepare for a new trackpad generation
  Input: synaptics - dump ext10 capabilities as well
parents 0a552051 3213afb8
...@@ -546,6 +546,12 @@ static const struct hid_device_id apple_devices[] = { ...@@ -546,6 +546,12 @@ static const struct hid_device_id apple_devices[] = {
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS), { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO),
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
......
...@@ -1782,6 +1782,9 @@ static const struct hid_device_id hid_have_special_driver[] = { ...@@ -1782,6 +1782,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
...@@ -2463,6 +2466,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { ...@@ -2463,6 +2466,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
{ } { }
......
...@@ -142,6 +142,9 @@ ...@@ -142,6 +142,9 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver
* *
* Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) * Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se)
* Copyright (C) 2015 John Horan (knasher@gmail.com)
* *
* The USB initialization and package decoding was made by * The USB initialization and package decoding was made by
* Scott Shawcroft as part of the touchd user-space driver project: * Scott Shawcroft as part of the touchd user-space driver project:
...@@ -91,6 +92,10 @@ ...@@ -91,6 +92,10 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
/* MacbookPro12,1 (2015) */
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
#define BCM5974_DEVICE(prod) { \ #define BCM5974_DEVICE(prod) { \
.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
...@@ -152,6 +157,10 @@ static const struct usb_device_id bcm5974_table[] = { ...@@ -152,6 +157,10 @@ static const struct usb_device_id bcm5974_table[] = {
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
/* MacbookPro12,1 */
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ISO),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
/* Terminating entry */ /* Terminating entry */
{} {}
}; };
...@@ -180,21 +189,47 @@ struct bt_data { ...@@ -180,21 +189,47 @@ struct bt_data {
enum tp_type { enum tp_type {
TYPE1, /* plain trackpad */ TYPE1, /* plain trackpad */
TYPE2, /* button integrated in trackpad */ TYPE2, /* button integrated in trackpad */
TYPE3 /* additional header fields since June 2013 */ TYPE3, /* additional header fields since June 2013 */
TYPE4 /* additional header field for pressure data */
}; };
/* trackpad finger data offsets, le16-aligned */ /* trackpad finger data offsets, le16-aligned */
#define FINGER_TYPE1 (13 * sizeof(__le16)) #define HEADER_TYPE1 (13 * sizeof(__le16))
#define FINGER_TYPE2 (15 * sizeof(__le16)) #define HEADER_TYPE2 (15 * sizeof(__le16))
#define FINGER_TYPE3 (19 * sizeof(__le16)) #define HEADER_TYPE3 (19 * sizeof(__le16))
#define HEADER_TYPE4 (23 * sizeof(__le16))
/* trackpad button data offsets */ /* trackpad button data offsets */
#define BUTTON_TYPE1 0
#define BUTTON_TYPE2 15 #define BUTTON_TYPE2 15
#define BUTTON_TYPE3 23 #define BUTTON_TYPE3 23
#define BUTTON_TYPE4 31
/* list of device capability bits */ /* list of device capability bits */
#define HAS_INTEGRATED_BUTTON 1 #define HAS_INTEGRATED_BUTTON 1
/* trackpad finger data block size */
#define FSIZE_TYPE1 (14 * sizeof(__le16))
#define FSIZE_TYPE2 (14 * sizeof(__le16))
#define FSIZE_TYPE3 (14 * sizeof(__le16))
#define FSIZE_TYPE4 (15 * sizeof(__le16))
/* offset from header to finger struct */
#define DELTA_TYPE1 (0 * sizeof(__le16))
#define DELTA_TYPE2 (0 * sizeof(__le16))
#define DELTA_TYPE3 (0 * sizeof(__le16))
#define DELTA_TYPE4 (1 * sizeof(__le16))
/* usb control message mode switch data */
#define USBMSG_TYPE1 8, 0x300, 0, 0, 0x1, 0x8
#define USBMSG_TYPE2 8, 0x300, 0, 0, 0x1, 0x8
#define USBMSG_TYPE3 8, 0x300, 0, 0, 0x1, 0x8
#define USBMSG_TYPE4 2, 0x302, 2, 1, 0x1, 0x0
/* Wellspring initialization constants */
#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1
#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9
/* trackpad finger structure, le16-aligned */ /* trackpad finger structure, le16-aligned */
struct tp_finger { struct tp_finger {
__le16 origin; /* zero when switching track finger */ __le16 origin; /* zero when switching track finger */
...@@ -207,14 +242,13 @@ struct tp_finger { ...@@ -207,14 +242,13 @@ struct tp_finger {
__le16 orientation; /* 16384 when point, else 15 bit angle */ __le16 orientation; /* 16384 when point, else 15 bit angle */
__le16 touch_major; /* touch area, major axis */ __le16 touch_major; /* touch area, major axis */
__le16 touch_minor; /* touch area, minor axis */ __le16 touch_minor; /* touch area, minor axis */
__le16 unused[3]; /* zeros */ __le16 unused[2]; /* zeros */
__le16 pressure; /* pressure on forcetouch touchpad */
__le16 multi; /* one finger: varies, more fingers: constant */ __le16 multi; /* one finger: varies, more fingers: constant */
} __attribute__((packed,aligned(2))); } __attribute__((packed,aligned(2)));
/* trackpad finger data size, empirically at least ten fingers */ /* trackpad finger data size, empirically at least ten fingers */
#define MAX_FINGERS 16 #define MAX_FINGERS 16
#define SIZEOF_FINGER sizeof(struct tp_finger)
#define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER)
#define MAX_FINGER_ORIENTATION 16384 #define MAX_FINGER_ORIENTATION 16384
/* device-specific parameters */ /* device-specific parameters */
...@@ -232,8 +266,17 @@ struct bcm5974_config { ...@@ -232,8 +266,17 @@ struct bcm5974_config {
int bt_datalen; /* data length of the button interface */ int bt_datalen; /* data length of the button interface */
int tp_ep; /* the endpoint of the trackpad interface */ int tp_ep; /* the endpoint of the trackpad interface */
enum tp_type tp_type; /* type of trackpad interface */ enum tp_type tp_type; /* type of trackpad interface */
int tp_offset; /* offset to trackpad finger data */ int tp_header; /* bytes in header block */
int tp_datalen; /* data length of the trackpad interface */ int tp_datalen; /* data length of the trackpad interface */
int tp_button; /* offset to button data */
int tp_fsize; /* bytes in single finger block */
int tp_delta; /* offset from header to finger struct */
int um_size; /* usb control message length */
int um_req_val; /* usb control message value */
int um_req_idx; /* usb control message index */
int um_switch_idx; /* usb control message mode switch index */
int um_switch_on; /* usb control message mode switch on */
int um_switch_off; /* usb control message mode switch off */
struct bcm5974_param p; /* finger pressure limits */ struct bcm5974_param p; /* finger pressure limits */
struct bcm5974_param w; /* finger width limits */ struct bcm5974_param w; /* finger width limits */
struct bcm5974_param x; /* horizontal limits */ struct bcm5974_param x; /* horizontal limits */
...@@ -259,6 +302,24 @@ struct bcm5974 { ...@@ -259,6 +302,24 @@ struct bcm5974 {
int slots[MAX_FINGERS]; /* slot assignments */ int slots[MAX_FINGERS]; /* slot assignments */
}; };
/* trackpad finger block data, le16-aligned */
static const struct tp_finger *get_tp_finger(const struct bcm5974 *dev, int i)
{
const struct bcm5974_config *c = &dev->cfg;
u8 *f_base = dev->tp_data + c->tp_header + c->tp_delta;
return (const struct tp_finger *)(f_base + i * c->tp_fsize);
}
#define DATAFORMAT(type) \
type, \
HEADER_##type, \
HEADER_##type + (MAX_FINGERS) * (FSIZE_##type), \
BUTTON_##type, \
FSIZE_##type, \
DELTA_##type, \
USBMSG_##type
/* logical signal quality */ /* logical signal quality */
#define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */
#define SN_WIDTH 25 /* width signal-to-noise ratio */ #define SN_WIDTH 25 /* width signal-to-noise ratio */
...@@ -273,7 +334,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -273,7 +334,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING_JIS, USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
0, 0,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE1),
{ SN_PRESSURE, 0, 256 }, { SN_PRESSURE, 0, 256 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4824, 5342 }, { SN_COORD, -4824, 5342 },
...@@ -286,7 +347,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -286,7 +347,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
0, 0,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE1),
{ SN_PRESSURE, 0, 256 }, { SN_PRESSURE, 0, 256 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4824, 4824 }, { SN_COORD, -4824, 4824 },
...@@ -299,7 +360,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -299,7 +360,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4460, 5166 }, { SN_COORD, -4460, 5166 },
...@@ -312,7 +373,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -312,7 +373,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING4_JIS, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4620, 5140 }, { SN_COORD, -4620, 5140 },
...@@ -325,7 +386,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -325,7 +386,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4616, 5112 }, { SN_COORD, -4616, 5112 },
...@@ -338,7 +399,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -338,7 +399,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING5_JIS, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4415, 5050 }, { SN_COORD, -4415, 5050 },
...@@ -351,7 +412,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -351,7 +412,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING6_JIS, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4620, 5140 }, { SN_COORD, -4620, 5140 },
...@@ -364,7 +425,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -364,7 +425,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4750, 5280 }, { SN_COORD, -4750, 5280 },
...@@ -377,7 +438,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -377,7 +438,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4620, 5140 }, { SN_COORD, -4620, 5140 },
...@@ -390,7 +451,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -390,7 +451,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4750, 5280 }, { SN_COORD, -4750, 5280 },
...@@ -403,7 +464,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -403,7 +464,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data), 0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 0x81, DATAFORMAT(TYPE2),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4750, 5280 }, { SN_COORD, -4750, 5280 },
...@@ -416,13 +477,26 @@ static const struct bcm5974_config bcm5974_config_table[] = { ...@@ -416,13 +477,26 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING8_JIS, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS,
HAS_INTEGRATED_BUTTON, HAS_INTEGRATED_BUTTON,
0, sizeof(struct bt_data), 0, sizeof(struct bt_data),
0x83, TYPE3, FINGER_TYPE3, FINGER_TYPE3 + SIZEOF_ALL_FINGERS, 0x83, DATAFORMAT(TYPE3),
{ SN_PRESSURE, 0, 300 }, { SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 }, { SN_WIDTH, 0, 2048 },
{ SN_COORD, -4620, 5140 }, { SN_COORD, -4620, 5140 },
{ SN_COORD, -150, 6600 }, { SN_COORD, -150, 6600 },
{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
}, },
{
USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI,
USB_DEVICE_ID_APPLE_WELLSPRING9_ISO,
USB_DEVICE_ID_APPLE_WELLSPRING9_JIS,
HAS_INTEGRATED_BUTTON,
0, sizeof(struct bt_data),
0x83, DATAFORMAT(TYPE4),
{ SN_PRESSURE, 0, 300 },
{ SN_WIDTH, 0, 2048 },
{ SN_COORD, -4828, 5345 },
{ SN_COORD, -203, 6803 },
{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
},
{} {}
}; };
...@@ -549,19 +623,18 @@ static int report_tp_state(struct bcm5974 *dev, int size) ...@@ -549,19 +623,18 @@ static int report_tp_state(struct bcm5974 *dev, int size)
struct input_dev *input = dev->input; struct input_dev *input = dev->input;
int raw_n, i, n = 0; int raw_n, i, n = 0;
if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) if (size < c->tp_header || (size - c->tp_header) % c->tp_fsize != 0)
return -EIO; return -EIO;
/* finger data, le16-aligned */ raw_n = (size - c->tp_header) / c->tp_fsize;
f = (const struct tp_finger *)(dev->tp_data + c->tp_offset);
raw_n = (size - c->tp_offset) / SIZEOF_FINGER;
for (i = 0; i < raw_n; i++) { for (i = 0; i < raw_n; i++) {
if (raw2int(f[i].touch_major) == 0) f = get_tp_finger(dev, i);
if (raw2int(f->touch_major) == 0)
continue; continue;
dev->pos[n].x = raw2int(f[i].abs_x); dev->pos[n].x = raw2int(f->abs_x);
dev->pos[n].y = c->y.min + c->y.max - raw2int(f[i].abs_y); dev->pos[n].y = c->y.min + c->y.max - raw2int(f->abs_y);
dev->index[n++] = &f[i]; dev->index[n++] = f;
} }
input_mt_assign_slots(input, dev->slots, dev->pos, n, 0); input_mt_assign_slots(input, dev->slots, dev->pos, n, 0);
...@@ -572,32 +645,22 @@ static int report_tp_state(struct bcm5974 *dev, int size) ...@@ -572,32 +645,22 @@ static int report_tp_state(struct bcm5974 *dev, int size)
input_mt_sync_frame(input); input_mt_sync_frame(input);
report_synaptics_data(input, c, f, raw_n); report_synaptics_data(input, c, get_tp_finger(dev, 0), raw_n);
/* type 2 reports button events via ibt only */ /* later types report button events via integrated button only */
if (c->tp_type == TYPE2) { if (c->caps & HAS_INTEGRATED_BUTTON) {
int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); int ibt = raw2int(dev->tp_data[c->tp_button]);
input_report_key(input, BTN_LEFT, ibt); input_report_key(input, BTN_LEFT, ibt);
} }
if (c->tp_type == TYPE3)
input_report_key(input, BTN_LEFT, dev->tp_data[BUTTON_TYPE3]);
input_sync(input); input_sync(input);
return 0; return 0;
} }
/* Wellspring initialization constants */
#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1
#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9
#define BCM5974_WELLSPRING_MODE_REQUEST_VALUE 0x300
#define BCM5974_WELLSPRING_MODE_REQUEST_INDEX 0
#define BCM5974_WELLSPRING_MODE_VENDOR_VALUE 0x01
#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE 0x08
static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
{ {
const struct bcm5974_config *c = &dev->cfg;
int retval = 0, size; int retval = 0, size;
char *data; char *data;
...@@ -605,7 +668,7 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) ...@@ -605,7 +668,7 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
if (dev->cfg.tp_type == TYPE3) if (dev->cfg.tp_type == TYPE3)
return 0; return 0;
data = kmalloc(8, GFP_KERNEL); data = kmalloc(c->um_size, GFP_KERNEL);
if (!data) { if (!data) {
dev_err(&dev->intf->dev, "out of memory\n"); dev_err(&dev->intf->dev, "out of memory\n");
retval = -ENOMEM; retval = -ENOMEM;
...@@ -616,28 +679,24 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) ...@@ -616,28 +679,24 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
BCM5974_WELLSPRING_MODE_READ_REQUEST_ID, BCM5974_WELLSPRING_MODE_READ_REQUEST_ID,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
BCM5974_WELLSPRING_MODE_REQUEST_VALUE, c->um_req_val, c->um_req_idx, data, c->um_size, 5000);
BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
if (size != 8) { if (size != c->um_size) {
dev_err(&dev->intf->dev, "could not read from device\n"); dev_err(&dev->intf->dev, "could not read from device\n");
retval = -EIO; retval = -EIO;
goto out; goto out;
} }
/* apply the mode switch */ /* apply the mode switch */
data[0] = on ? data[c->um_switch_idx] = on ? c->um_switch_on : c->um_switch_off;
BCM5974_WELLSPRING_MODE_VENDOR_VALUE :
BCM5974_WELLSPRING_MODE_NORMAL_VALUE;
/* write configuration */ /* write configuration */
size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID, BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
BCM5974_WELLSPRING_MODE_REQUEST_VALUE, c->um_req_val, c->um_req_idx, data, c->um_size, 5000);
BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
if (size != 8) { if (size != c->um_size) {
dev_err(&dev->intf->dev, "could not write to device\n"); dev_err(&dev->intf->dev, "could not write to device\n");
retval = -EIO; retval = -EIO;
goto out; goto out;
......
...@@ -1484,12 +1484,12 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) ...@@ -1484,12 +1484,12 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
psmouse_info(psmouse, psmouse_info(psmouse,
"Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n", "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n",
SYN_ID_MODEL(priv->identity), SYN_ID_MODEL(priv->identity),
SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
priv->model_id, priv->model_id,
priv->capabilities, priv->ext_cap, priv->ext_cap_0c, priv->capabilities, priv->ext_cap, priv->ext_cap_0c,
priv->board_id, priv->firmware_id); priv->ext_cap_10, priv->board_id, priv->firmware_id);
set_input_params(psmouse, priv); set_input_params(psmouse, priv);
......
...@@ -429,7 +429,7 @@ static int zforce_read_packet(struct zforce_ts *ts, u8 *buf) ...@@ -429,7 +429,7 @@ static int zforce_read_packet(struct zforce_ts *ts, u8 *buf)
goto unlock; goto unlock;
} }
if (buf[PAYLOAD_LENGTH] == 0 || buf[PAYLOAD_LENGTH] > FRAME_MAXSIZE) { if (buf[PAYLOAD_LENGTH] == 0) {
dev_err(&client->dev, "invalid payload length: %d\n", dev_err(&client->dev, "invalid payload length: %d\n",
buf[PAYLOAD_LENGTH]); buf[PAYLOAD_LENGTH]);
ret = -EIO; ret = -EIO;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment