Commit 7686ad56 authored by Linus Torvalds's avatar Linus Torvalds

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

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: i8042 - make Lenovo 3000 N100 blacklist entry more specific
  Input: bcm5974 - add BTN_TOUCH event for mousedev benefit
  Input: bcm5974 - improve finger tracking and counting
  Input: bcm5974 - small formatting cleanup
  Input: bcm5974 - add maintainer entry
parents 64f996f6 9ce1ca28
......@@ -63,7 +63,7 @@
}
/* table of devices that work with this driver */
static const struct usb_device_id bcm5974_table [] = {
static const struct usb_device_id bcm5974_table[] = {
/* MacbookAir1.1 */
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
......@@ -105,7 +105,7 @@ struct tp_header {
/* trackpad finger structure */
struct tp_finger {
__le16 origin; /* left/right origin? */
__le16 origin; /* zero when switching track finger */
__le16 abs_x; /* absolute x coodinate */
__le16 abs_y; /* absolute y coodinate */
__le16 rel_x; /* relative x coodinate */
......@@ -159,6 +159,7 @@ struct bcm5974 {
struct bt_data *bt_data; /* button transferred data */
struct urb *tp_urb; /* trackpad usb request block */
struct tp_data *tp_data; /* trackpad transferred data */
int fingers; /* number of fingers on trackpad */
};
/* logical dimensions */
......@@ -172,6 +173,10 @@ struct bcm5974 {
#define SN_WIDTH 100 /* width signal-to-noise ratio */
#define SN_COORD 250 /* coordinate signal-to-noise ratio */
/* pressure thresholds */
#define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE)
#define PRESSURE_HIGH (3 * PRESSURE_LOW)
/* device constants */
static const struct bcm5974_config bcm5974_config_table[] = {
{
......@@ -248,6 +253,7 @@ static void setup_events_to_report(struct input_dev *input_dev,
0, cfg->y.dim, cfg->y.fuzz, 0);
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(BTN_TOUCH, input_dev->keybit);
__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
......@@ -273,32 +279,66 @@ static int report_tp_state(struct bcm5974 *dev, int size)
const struct tp_finger *f = dev->tp_data->finger;
struct input_dev *input = dev->input;
const int fingers = (size - 26) / 28;
int p = 0, w, x, y, n = 0;
int raw_p, raw_w, raw_x, raw_y;
int ptest = 0, origin = 0, nmin = 0, nmax = 0;
int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
if (size < 26 || (size - 26) % 28 != 0)
return -EIO;
/* always track the first finger; when detached, start over */
if (fingers) {
p = raw2int(f->force_major);
w = raw2int(f->size_major);
x = raw2int(f->abs_x);
y = raw2int(f->abs_y);
n = p > 0 ? fingers : 0;
raw_p = raw2int(f->force_major);
raw_w = raw2int(f->size_major);
raw_x = raw2int(f->abs_x);
raw_y = raw2int(f->abs_y);
dprintk(9,
"bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
p, w, x, y, n);
"bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n",
raw_p, raw_w, raw_x, raw_y);
ptest = int2bound(&c->p, raw_p);
origin = raw2int(f->origin);
}
input_report_abs(input, ABS_TOOL_WIDTH, int2bound(&c->w, w));
input_report_abs(input, ABS_X, int2bound(&c->x, x - c->x.devmin));
input_report_abs(input, ABS_Y, int2bound(&c->y, c->y.devmax - y));
/* while tracking finger still valid, count all fingers */
if (ptest > PRESSURE_LOW && origin) {
abs_p = ptest;
abs_w = int2bound(&c->w, raw_w);
abs_x = int2bound(&c->x, raw_x - c->x.devmin);
abs_y = int2bound(&c->y, c->y.devmax - raw_y);
for (; f != dev->tp_data->finger + fingers; f++) {
ptest = int2bound(&c->p, raw2int(f->force_major));
if (ptest > PRESSURE_LOW)
nmax++;
if (ptest > PRESSURE_HIGH)
nmin++;
}
}
input_report_abs(input, ABS_PRESSURE, int2bound(&c->p, p));
if (dev->fingers < nmin)
dev->fingers = nmin;
if (dev->fingers > nmax)
dev->fingers = nmax;
input_report_key(input, BTN_TOUCH, dev->fingers > 0);
input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2);
input_report_key(input, BTN_TOOL_FINGER, n == 1);
input_report_key(input, BTN_TOOL_DOUBLETAP, n == 2);
input_report_key(input, BTN_TOOL_TRIPLETAP, n > 2);
input_report_abs(input, ABS_PRESSURE, abs_p);
input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
if (abs_p) {
input_report_abs(input, ABS_X, abs_x);
input_report_abs(input, ABS_Y, abs_y);
dprintk(8,
"bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
"nmin: %d nmax: %d n: %d\n",
abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers);
}
input_sync(input);
......
......@@ -305,7 +305,7 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
.ident = "Lenovo 3000 n100",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
},
},
{
......
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