Skip to content

Commit 7686ad5

Browse files
committed
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
2 parents 64f996f + 9ce1ca2 commit 7686ad5

File tree

2 files changed

+58
-18
lines changed

2 files changed

+58
-18
lines changed

drivers/input/mouse/bcm5974.c

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
}
6464

6565
/* table of devices that work with this driver */
66-
static const struct usb_device_id bcm5974_table [] = {
66+
static const struct usb_device_id bcm5974_table[] = {
6767
/* MacbookAir1.1 */
6868
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
6969
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
@@ -105,7 +105,7 @@ struct tp_header {
105105

106106
/* trackpad finger structure */
107107
struct tp_finger {
108-
__le16 origin; /* left/right origin? */
108+
__le16 origin; /* zero when switching track finger */
109109
__le16 abs_x; /* absolute x coodinate */
110110
__le16 abs_y; /* absolute y coodinate */
111111
__le16 rel_x; /* relative x coodinate */
@@ -159,6 +159,7 @@ struct bcm5974 {
159159
struct bt_data *bt_data; /* button transferred data */
160160
struct urb *tp_urb; /* trackpad usb request block */
161161
struct tp_data *tp_data; /* trackpad transferred data */
162+
int fingers; /* number of fingers on trackpad */
162163
};
163164

164165
/* logical dimensions */
@@ -172,6 +173,10 @@ struct bcm5974 {
172173
#define SN_WIDTH 100 /* width signal-to-noise ratio */
173174
#define SN_COORD 250 /* coordinate signal-to-noise ratio */
174175

176+
/* pressure thresholds */
177+
#define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE)
178+
#define PRESSURE_HIGH (3 * PRESSURE_LOW)
179+
175180
/* device constants */
176181
static const struct bcm5974_config bcm5974_config_table[] = {
177182
{
@@ -248,6 +253,7 @@ static void setup_events_to_report(struct input_dev *input_dev,
248253
0, cfg->y.dim, cfg->y.fuzz, 0);
249254

250255
__set_bit(EV_KEY, input_dev->evbit);
256+
__set_bit(BTN_TOUCH, input_dev->keybit);
251257
__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
252258
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
253259
__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
@@ -273,32 +279,66 @@ static int report_tp_state(struct bcm5974 *dev, int size)
273279
const struct tp_finger *f = dev->tp_data->finger;
274280
struct input_dev *input = dev->input;
275281
const int fingers = (size - 26) / 28;
276-
int p = 0, w, x, y, n = 0;
282+
int raw_p, raw_w, raw_x, raw_y;
283+
int ptest = 0, origin = 0, nmin = 0, nmax = 0;
284+
int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
277285

278286
if (size < 26 || (size - 26) % 28 != 0)
279287
return -EIO;
280288

289+
/* always track the first finger; when detached, start over */
281290
if (fingers) {
282-
p = raw2int(f->force_major);
283-
w = raw2int(f->size_major);
284-
x = raw2int(f->abs_x);
285-
y = raw2int(f->abs_y);
286-
n = p > 0 ? fingers : 0;
291+
raw_p = raw2int(f->force_major);
292+
raw_w = raw2int(f->size_major);
293+
raw_x = raw2int(f->abs_x);
294+
raw_y = raw2int(f->abs_y);
287295

288296
dprintk(9,
289-
"bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
290-
p, w, x, y, n);
297+
"bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n",
298+
raw_p, raw_w, raw_x, raw_y);
299+
300+
ptest = int2bound(&c->p, raw_p);
301+
origin = raw2int(f->origin);
302+
}
291303

292-
input_report_abs(input, ABS_TOOL_WIDTH, int2bound(&c->w, w));
293-
input_report_abs(input, ABS_X, int2bound(&c->x, x - c->x.devmin));
294-
input_report_abs(input, ABS_Y, int2bound(&c->y, c->y.devmax - y));
304+
/* while tracking finger still valid, count all fingers */
305+
if (ptest > PRESSURE_LOW && origin) {
306+
abs_p = ptest;
307+
abs_w = int2bound(&c->w, raw_w);
308+
abs_x = int2bound(&c->x, raw_x - c->x.devmin);
309+
abs_y = int2bound(&c->y, c->y.devmax - raw_y);
310+
for (; f != dev->tp_data->finger + fingers; f++) {
311+
ptest = int2bound(&c->p, raw2int(f->force_major));
312+
if (ptest > PRESSURE_LOW)
313+
nmax++;
314+
if (ptest > PRESSURE_HIGH)
315+
nmin++;
316+
}
295317
}
296318

297-
input_report_abs(input, ABS_PRESSURE, int2bound(&c->p, p));
319+
if (dev->fingers < nmin)
320+
dev->fingers = nmin;
321+
if (dev->fingers > nmax)
322+
dev->fingers = nmax;
323+
324+
input_report_key(input, BTN_TOUCH, dev->fingers > 0);
325+
input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
326+
input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
327+
input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2);
298328

299-
input_report_key(input, BTN_TOOL_FINGER, n == 1);
300-
input_report_key(input, BTN_TOOL_DOUBLETAP, n == 2);
301-
input_report_key(input, BTN_TOOL_TRIPLETAP, n > 2);
329+
input_report_abs(input, ABS_PRESSURE, abs_p);
330+
input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
331+
332+
if (abs_p) {
333+
input_report_abs(input, ABS_X, abs_x);
334+
input_report_abs(input, ABS_Y, abs_y);
335+
336+
dprintk(8,
337+
"bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
338+
"nmin: %d nmax: %d n: %d\n",
339+
abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers);
340+
341+
}
302342

303343
input_sync(input);
304344

drivers/input/serio/i8042-x86ia64io.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
305305
.ident = "Lenovo 3000 n100",
306306
.matches = {
307307
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
308-
DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
308+
DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
309309
},
310310
},
311311
{

0 commit comments

Comments
 (0)