From patchwork Sun Aug 26 12:57:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henrik Rydberg X-Patchwork-Id: 1375041 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 592EBDFABE for ; Sun, 26 Aug 2012 12:55:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751691Ab2HZMyK (ORCPT ); Sun, 26 Aug 2012 08:54:10 -0400 Received: from smtprelay-b21.telenor.se ([195.54.99.212]:47408 "EHLO smtprelay-b21.telenor.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751457Ab2HZMyJ (ORCPT ); Sun, 26 Aug 2012 08:54:09 -0400 Received: from ipb2.telenor.se (ipb2.telenor.se [195.54.127.165]) by smtprelay-b21.telenor.se (Postfix) with ESMTP id D80A6C649; Sun, 26 Aug 2012 14:54:07 +0200 (CEST) X-SENDER-IP: [85.230.170.20] X-LISTENER: [smtp.bredband.net] X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApVZADUbOlBV5qoUPGdsb2JhbABFhRqFI7AtGQEBAQEeGQ0ngiEBBScvEwEPEAhJOQoUBgEJCYgRu0kUkgUDm0CNDw X-IronPort-AV: E=Sophos;i="4.77,830,1336341600"; d="scan'208";a="397048814" Received: from c-14aae655.710-13-64736c12.cust.bredbandsbolaget.se (HELO polaris) ([85.230.170.20]) by ipb2.telenor.se with SMTP; 26 Aug 2012 14:54:06 +0200 Received: by polaris (sSMTP sendmail emulation); Sun, 26 Aug 2012 14:59:24 +0200 From: "Henrik Rydberg" To: Dmitry Torokhov , Jiri Kosina Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Henrik Rydberg Subject: [PATCH 16/20] Input: bcm5974 - Convert to MT-B Date: Sun, 26 Aug 2012 14:57:34 +0200 Message-Id: <1345985858-445-17-git-send-email-rydberg@euromail.se> X-Mailer: git-send-email 1.7.12 In-Reply-To: <1345985858-445-1-git-send-email-rydberg@euromail.se> References: <1345985858-445-1-git-send-email-rydberg@euromail.se> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Use of the in-kernel tracking code to convert the driver to MT-B. With ten fingers on the pad, the in-kernel tracking adds approximately 25 us to the maximum irqsoff latency. Under normal workloads, however, the tracking has no measurable effect. Signed-off-by: Henrik Rydberg --- drivers/input/mouse/bcm5974.c | 80 +++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 53 deletions(-) diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 4254a38..9555aa5 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -40,6 +40,7 @@ #include #include #include +#include #define USB_VENDOR_ID_APPLE 0x05ac @@ -234,6 +235,9 @@ struct bcm5974 { struct bt_data *bt_data; /* button transferred data */ struct urb *tp_urb; /* trackpad usb request block */ u8 *tp_data; /* trackpad transferred data */ + const struct tp_finger *index[MAX_FINGERS]; /* finger index data */ + struct input_mt_pos pos[MAX_FINGERS]; /* position array */ + int slots[MAX_FINGERS]; /* slot assignments */ }; /* logical signal quality */ @@ -398,10 +402,6 @@ static void setup_events_to_report(struct input_dev *input_dev, { __set_bit(EV_ABS, input_dev->evbit); - /* pointer emulation */ - set_abs(input_dev, ABS_X, &cfg->w); - set_abs(input_dev, ABS_Y, &cfg->w); - /* finger touch area */ set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w); set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w); @@ -415,16 +415,13 @@ static void setup_events_to_report(struct input_dev *input_dev, set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y); __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); - __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); __set_bit(BTN_LEFT, input_dev->keybit); - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); if (cfg->caps & HAS_INTEGRATED_BUTTON) __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); + + input_mt_init_slots(input_dev, MAX_FINGERS, + INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); } /* report button data as logical button state */ @@ -444,10 +441,13 @@ static int report_bt_state(struct bcm5974 *dev, int size) return 0; } -static void report_finger_data(struct input_dev *input, - const struct bcm5974_config *cfg, +static void report_finger_data(struct input_dev *input, int slot, + const struct input_mt_pos *pos, const struct tp_finger *f) { + input_mt_slot(input, slot); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->touch_major) << 1); input_report_abs(input, ABS_MT_TOUCH_MINOR, @@ -458,10 +458,8 @@ static void report_finger_data(struct input_dev *input, raw2int(f->tool_minor) << 1); input_report_abs(input, ABS_MT_ORIENTATION, MAX_FINGER_ORIENTATION - raw2int(f->orientation)); - input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); - input_report_abs(input, ABS_MT_POSITION_Y, - cfg->y.min + cfg->y.max - raw2int(f->abs_y)); - input_mt_sync(input); + input_report_abs(input, ABS_MT_POSITION_X, pos->x); + input_report_abs(input, ABS_MT_POSITION_Y, pos->y); } /* report trackpad data as logical trackpad state */ @@ -470,8 +468,7 @@ static int report_tp_state(struct bcm5974 *dev, int size) const struct bcm5974_config *c = &dev->cfg; const struct tp_finger *f; struct input_dev *input = dev->input; - int raw_p, raw_x, raw_y, raw_n, i; - int abs_x = 0, abs_y = 0, n = 0; + int raw_n, i, n = 0; if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) return -EIO; @@ -480,44 +477,21 @@ static int report_tp_state(struct bcm5974 *dev, int size) f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); raw_n = (size - c->tp_offset) / SIZEOF_FINGER; - /* always track the first finger; when detached, start over */ - if (raw_n) { - - /* report raw trackpad data */ - for (i = 0; i < raw_n; i++) - report_finger_data(input, c, &f[i]); - - raw_p = raw2int(f->touch_major); - raw_x = raw2int(f->abs_x); - raw_y = raw2int(f->abs_y); - - dprintk(9, - "bcm5974: " - "raw: p: %+05d x: %+05d y: %+05d n: %d\n", - raw_p, raw_x, raw_y, raw_n); - - /* while tracking finger still valid, count all fingers */ - if (raw_p > 0 && raw2int(f->origin)) { - abs_x = raw_x; - abs_y = c->y.min + c->y.max - raw_y; - while (raw_n--) { - if (raw2int(f->touch_major) > 0) - n++; - f++; - } - } + for (i = 0; i < raw_n; i++) { + if (raw2int(f[i].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]; } - input_report_key(input, BTN_TOUCH, n > 0); - 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 == 3); - input_report_key(input, BTN_TOOL_QUADTAP, n > 3); + input_mt_assign_slots(input, dev->slots, dev->pos, n); - if (n > 0) { - input_report_abs(input, ABS_X, abs_x); - input_report_abs(input, ABS_Y, abs_y); - } + for (i = 0; i < n; i++) + report_finger_data(input, dev->slots[i], + &dev->pos[i], dev->index[i]); + + input_mt_sync_frame(input); /* type 2 reports button events via ibt only */ if (c->tp_type == TYPE2) {