Skip to content

Commit

Permalink
Input: bcm5974 - Add support for the Macbook 5 (Unibody)
Browse files Browse the repository at this point in the history
This patch adds support for the new unibody Macbook, with physically
integrated button and trackpad. Since the integrated button changes
the logic for touch-and-click, a device capability bit mask is now
reported in input_id.version, which can be picked up by user space
via a EVIOCGID call.

Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Tested-by: David M. Lary <dmlary@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
  • Loading branch information
Henrik Rydberg authored and Dmitry Torokhov committed Apr 28, 2009
1 parent 6916d97 commit 158e928
Showing 1 changed file with 43 additions and 2 deletions.
45 changes: 43 additions & 2 deletions drivers/input/mouse/bcm5974.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
/* Macbook5,1 (unibody), aka wellspring3 */
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238

#define BCM5974_DEVICE(prod) { \
.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
Expand All @@ -72,6 +76,10 @@ static const struct usb_device_id bcm5974_table[] = {
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
/* Macbook5,1 */
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
/* Terminating entry */
{}
};
Expand All @@ -98,11 +106,19 @@ struct bt_data {

/* trackpad header types */
enum tp_type {
TYPE1 /* plain trackpad */
TYPE1, /* plain trackpad */
TYPE2 /* button integrated in trackpad */
};

/* trackpad finger data offsets, le16-aligned */
#define FINGER_TYPE1 (13 * sizeof(__le16))
#define FINGER_TYPE2 (15 * sizeof(__le16))

/* trackpad button data offsets */
#define BUTTON_TYPE2 15

/* list of device capability bits */
#define HAS_INTEGRATED_BUTTON 1

/* trackpad finger structure, le16-aligned */
struct tp_finger {
Expand Down Expand Up @@ -135,6 +151,7 @@ struct bcm5974_param {
/* device-specific configuration */
struct bcm5974_config {
int ansi, iso, jis; /* the product id of this device */
int caps; /* device capability bitmask */
int bt_ep; /* the endpoint of the button interface */
int bt_datalen; /* data length of the button interface */
int tp_ep; /* the endpoint of the trackpad interface */
Expand Down Expand Up @@ -184,6 +201,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
0,
0x84, sizeof(struct bt_data),
0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
Expand All @@ -195,13 +213,26 @@ static const struct bcm5974_config bcm5974_config_table[] = {
USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
0,
0x84, sizeof(struct bt_data),
0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
{ DIM_X, DIM_X / SN_COORD, -4824, 4824 },
{ DIM_Y, DIM_Y / SN_COORD, -172, 4290 }
},
{
USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,
USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
HAS_INTEGRATED_BUTTON,
0x84, sizeof(struct bt_data),
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
{ DIM_X, DIM_X / SN_COORD, -4460, 5166 },
{ DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
},
{}
};

Expand Down Expand Up @@ -281,7 +312,7 @@ static int report_tp_state(struct bcm5974 *dev, int size)
const struct tp_finger *f;
struct input_dev *input = dev->input;
int raw_p, raw_w, raw_x, raw_y, raw_n;
int ptest = 0, origin = 0, nmin = 0, nmax = 0;
int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0;
int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;

if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
Expand All @@ -304,6 +335,10 @@ static int report_tp_state(struct bcm5974 *dev, int size)

ptest = int2bound(&c->p, raw_p);
origin = raw2int(f->origin);

/* set the integrated button if applicable */
if (c->tp_type == TYPE2)
ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
}

/* while tracking finger still valid, count all fingers */
Expand Down Expand Up @@ -347,6 +382,10 @@ static int report_tp_state(struct bcm5974 *dev, int size)

}

/* type 2 reports button events via ibt only */
if (c->tp_type == TYPE2)
input_report_key(input, BTN_LEFT, ibt);

input_sync(input);

return 0;
Expand Down Expand Up @@ -656,6 +695,8 @@ static int bcm5974_probe(struct usb_interface *iface,
input_dev->name = "bcm5974";
input_dev->phys = dev->phys;
usb_to_input_id(dev->udev, &input_dev->id);
/* report driver capabilities via the version field */
input_dev->id.version = cfg->caps;
input_dev->dev.parent = &iface->dev;

input_set_drvdata(input_dev, dev);
Expand Down

0 comments on commit 158e928

Please sign in to comment.