| centosplus patch (bug#10447) |
| support for touchpad and fn key support for MacBookPro 12,1 |
| |
| https://kernel.googlesource.com/pub/scm/linux/kernel/git/groeck/linux-staging/+/dbe08116b87cdc2217f11a78b5b70e29068b7efd%5E1..dbe08116b87cdc2217f11a78b5b70e29068b7efd/ |
| |
| 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 |
| |
| Applied-by Akemi Yagi <toracat@centos.org> |
| |
| |
| |
| @@ -552,6 +552,12 @@ static const struct hid_device_id apple_ |
| .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
| { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_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), |
| .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), |
| |
| |
| @@ -1643,6 +1643,9 @@ static const struct hid_device_id hid_ha |
| { 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_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_ISO) }, |
| { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
| @@ -2284,6 +2287,9 @@ static const struct hid_device_id hid_mo |
| { 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_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_GEYSER1_TP_ONLY) }, |
| { } |
| |
| |
| @@ -138,6 +138,9 @@ |
| #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 |
| #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 |
| #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_GEYSER1_TP_ONLY 0x030b |
| #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 |
| |
| |
| @@ -2,6 +2,7 @@ |
| * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver |
| * |
| * 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 |
| * Scott Shawcroft as part of the touchd user-space driver project: |
| @@ -92,6 +93,10 @@ |
| #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 |
| #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 |
| #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) { \ |
| .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
| @@ -153,6 +158,10 @@ static const struct usb_device_id bcm597 |
| BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI), |
| BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO), |
| 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 */ |
| {} |
| }; |
| @@ -181,21 +190,47 @@ struct bt_data { |
| enum tp_type { |
| TYPE1, /* plain 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 */ |
| -#define FINGER_TYPE1 (13 * sizeof(__le16)) |
| -#define FINGER_TYPE2 (15 * sizeof(__le16)) |
| -#define FINGER_TYPE3 (19 * sizeof(__le16)) |
| +#define HEADER_TYPE1 (13 * sizeof(__le16)) |
| +#define HEADER_TYPE2 (15 * sizeof(__le16)) |
| +#define HEADER_TYPE3 (19 * sizeof(__le16)) |
| +#define HEADER_TYPE4 (23 * sizeof(__le16)) |
| |
| /* trackpad button data offsets */ |
| +#define BUTTON_TYPE1 0 |
| #define BUTTON_TYPE2 15 |
| #define BUTTON_TYPE3 23 |
| +#define BUTTON_TYPE4 31 |
| |
| /* list of device capability bits */ |
| #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 */ |
| struct tp_finger { |
| __le16 origin; /* zero when switching track finger */ |
| @@ -208,14 +243,13 @@ struct tp_finger { |
| __le16 orientation; /* 16384 when point, else 15 bit angle */ |
| __le16 touch_major; /* touch area, major 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 */ |
| } __attribute__((packed,aligned(2))); |
| |
| /* trackpad finger data size, empirically at least ten fingers */ |
| #define MAX_FINGERS 16 |
| -#define SIZEOF_FINGER sizeof(struct tp_finger) |
| -#define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) |
| #define MAX_FINGER_ORIENTATION 16384 |
| |
| /* device-specific parameters */ |
| @@ -233,8 +267,17 @@ struct bcm5974_config { |
| int bt_datalen; /* data length of the button interface */ |
| int tp_ep; /* the endpoint of the 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_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 w; /* finger width limits */ |
| struct bcm5974_param x; /* horizontal limits */ |
| @@ -260,6 +303,24 @@ struct bcm5974 { |
| 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 */ |
| #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ |
| #define SN_WIDTH 25 /* width signal-to-noise ratio */ |
| @@ -274,7 +335,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING_JIS, |
| 0, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE1), |
| { SN_PRESSURE, 0, 256 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4824, 5342 }, |
| @@ -287,7 +348,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, |
| 0, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE1), |
| { SN_PRESSURE, 0, 256 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4824, 4824 }, |
| @@ -300,7 +361,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4460, 5166 }, |
| @@ -313,7 +374,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING4_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4620, 5140 }, |
| @@ -326,7 +387,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4616, 5112 }, |
| @@ -339,7 +400,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING5_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4415, 5050 }, |
| @@ -352,7 +413,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING6_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4620, 5140 }, |
| @@ -365,7 +426,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4750, 5280 }, |
| @@ -378,7 +439,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4620, 5140 }, |
| @@ -391,7 +452,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4750, 5280 }, |
| @@ -404,7 +465,7 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0x84, sizeof(struct bt_data), |
| - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
| + 0x81, DATAFORMAT(TYPE2), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4750, 5280 }, |
| @@ -417,13 +478,26 @@ static const struct bcm5974_config bcm59 |
| USB_DEVICE_ID_APPLE_WELLSPRING8_JIS, |
| HAS_INTEGRATED_BUTTON, |
| 0, sizeof(struct bt_data), |
| - 0x83, TYPE3, FINGER_TYPE3, FINGER_TYPE3 + SIZEOF_ALL_FINGERS, |
| + 0x83, DATAFORMAT(TYPE3), |
| { SN_PRESSURE, 0, 300 }, |
| { SN_WIDTH, 0, 2048 }, |
| { SN_COORD, -4620, 5140 }, |
| { SN_COORD, -150, 6600 }, |
| { 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 } |
| + }, |
| {} |
| }; |
| |
| @@ -550,19 +624,18 @@ static int report_tp_state(struct bcm597 |
| struct input_dev *input = dev->input; |
| 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; |
| |
| - /* finger data, le16-aligned */ |
| - f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); |
| - raw_n = (size - c->tp_offset) / SIZEOF_FINGER; |
| + raw_n = (size - c->tp_header) / c->tp_fsize; |
| |
| 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; |
| - dev->pos[n].x = raw2int(f[i].abs_x); |
| - dev->pos[n].y = c->y.min + c->y.max - raw2int(f[i].abs_y); |
| - dev->index[n++] = &f[i]; |
| + dev->pos[n].x = raw2int(f->abs_x); |
| + dev->pos[n].y = c->y.min + c->y.max - raw2int(f->abs_y); |
| + dev->index[n++] = f; |
| } |
| |
| input_mt_assign_slots(input, dev->slots, dev->pos, n); |
| @@ -573,32 +646,22 @@ static int report_tp_state(struct bcm597 |
| |
| 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 */ |
| - if (c->tp_type == TYPE2) { |
| - int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); |
| + /* later types report button events via integrated button only */ |
| + if (c->caps & HAS_INTEGRATED_BUTTON) { |
| + int ibt = raw2int(dev->tp_data[c->tp_button]); |
| 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); |
| |
| 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) |
| { |
| + const struct bcm5974_config *c = &dev->cfg; |
| int retval = 0, size; |
| char *data; |
| |
| @@ -606,7 +669,7 @@ static int bcm5974_wellspring_mode(struc |
| if (dev->cfg.tp_type == TYPE3) |
| return 0; |
| |
| - data = kmalloc(8, GFP_KERNEL); |
| + data = kmalloc(c->um_size, GFP_KERNEL); |
| if (!data) { |
| dev_err(&dev->intf->dev, "out of memory\n"); |
| retval = -ENOMEM; |
| @@ -617,28 +680,24 @@ static int bcm5974_wellspring_mode(struc |
| size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), |
| BCM5974_WELLSPRING_MODE_READ_REQUEST_ID, |
| USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| - BCM5974_WELLSPRING_MODE_REQUEST_VALUE, |
| - BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); |
| + c->um_req_val, c->um_req_idx, data, c->um_size, 5000); |
| |
| - if (size != 8) { |
| + if (size != c->um_size) { |
| dev_err(&dev->intf->dev, "could not read from device\n"); |
| retval = -EIO; |
| goto out; |
| } |
| |
| /* apply the mode switch */ |
| - data[0] = on ? |
| - BCM5974_WELLSPRING_MODE_VENDOR_VALUE : |
| - BCM5974_WELLSPRING_MODE_NORMAL_VALUE; |
| + data[c->um_switch_idx] = on ? c->um_switch_on : c->um_switch_off; |
| |
| /* write configuration */ |
| size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), |
| BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID, |
| USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| - BCM5974_WELLSPRING_MODE_REQUEST_VALUE, |
| - BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); |
| + c->um_req_val, c->um_req_idx, data, c->um_size, 5000); |
| |
| - if (size != 8) { |
| + if (size != c->um_size) { |
| dev_err(&dev->intf->dev, "could not write to device\n"); |
| retval = -EIO; |
| goto out; |