From patchwork Tue Jul 3 20:22:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yufeng Shen X-Patchwork-Id: 1153051 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E3A4D3FE80 for ; Tue, 3 Jul 2012 20:22:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751899Ab2GCUWg (ORCPT ); Tue, 3 Jul 2012 16:22:36 -0400 Received: from mail-wi0-f202.google.com ([209.85.212.202]:60348 "EHLO mail-wi0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751298Ab2GCUWf (ORCPT ); Tue, 3 Jul 2012 16:22:35 -0400 Received: by wibhr14 with SMTP id hr14so270983wib.1 for ; Tue, 03 Jul 2012 13:22:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=PPq2/dSm3lpW/DVgI9iUdcZTXydx0ui7kCrjMd+ZoCk=; b=YhHlh5wZkjSwDuPr9K99T8Ig4zNoe9sNN/el8R5F887s/yPV6VNlBobccsvf0LvRjf +YsKve0LagOd2uy21x+KEmVUF8ARE5rT6+cMrVlIvwnBojVITwctl5XwaQ2oXvLthnOM U5s61x38xSAc0hjDRzc0MrK4VbgBhD4HjLRk3x02KCeBDzQ848S63Ac/WP2B7B7ghGUO yD2N4p8Un4/mD/paq1+FeYSId/mKYeufIyapPXEcJJKXuO7wZqA8vzHJx2h/uEwSSs/2 Tc+SVpTzRXZXu/kQUK0UBcDVGDHRb5spVUYe0RmPhIEFlvSefiLrFzUxF0Qoguj88BJN dfUw== Received: by 10.14.100.207 with SMTP id z55mr5680663eef.10.1341346953931; Tue, 03 Jul 2012 13:22:33 -0700 (PDT) Received: by 10.14.100.207 with SMTP id z55mr5680641eef.10.1341346953681; Tue, 03 Jul 2012 13:22:33 -0700 (PDT) Received: from hpza9.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id v14si11309887eef.2.2012.07.03.13.22.33 (version=TLSv1/SSLv3 cipher=AES128-SHA); Tue, 03 Jul 2012 13:22:33 -0700 (PDT) Received: from miletus1.wat.corp.google.com (miletus1.wat.corp.google.com [172.23.176.198]) by hpza9.eem.corp.google.com (Postfix) with ESMTP id 703A05C0050; Tue, 3 Jul 2012 13:22:33 -0700 (PDT) Received: by miletus1.wat.corp.google.com (Postfix, from userid 95428) id B2FCC16041A; Tue, 3 Jul 2012 16:22:32 -0400 (EDT) From: Yufeng Shen To: linux-input@vger.kernel.org Cc: Jiri Kosina , Henrik Rydberg , linux-kernel@vger.kernel.org, Daniel Kurtz , Andrew de los Reyes , Chase Douglas , Yufeng Shen Subject: [PATCH 2/2 v3] HID: magicmouse: Implement Multi-touch Protocol B (MT-B) Date: Tue, 3 Jul 2012 16:22:31 -0400 Message-Id: <1341346951-10974-1-git-send-email-miletus@chromium.org> X-Mailer: git-send-email 1.7.7.3 X-Gm-Message-State: ALoCoQlRLcSMij4mN643sr2BKK4Jui1HFEVwJB6sr1q8y7sx1Nay/WU2nRW/PtRJQma8pxV7WZW1hqrZ5qI2FehSUk8Ft4A1wXNJObAL2VkXNDXLnmG1cfcC8FmPlAQUP067AmhnVZOJqlDS3pQ3AfwgZJdg8JgpXk5wyvcfpNFTwF2JNibSP/BohOATZ02P9Sl5hH3bTgcL Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org The driver for Apple Magic Trackpad/Mouse currently uses Multi-touch Protocol A (MT-A) to report touch events and uses ABS_MT_TRACKING_ID to do finger tracking. The fact of the device being able to track individual finger makes it possible to report touch events using MT-B. This patch converts the driver to use MT-B as it is preferred to MT-A. V3: Removed the single touch related logic. V2: Converting entirely to MT-B as Henrik Rydberg suggested. Change-Id: I7eab3cd06f761e0e76f07540dcd38aa7ad7a048b Signed-off-by: Yufeng Shen --- drivers/hid/hid-magicmouse.c | 65 ++++++++++++++--------------------------- 1 files changed, 22 insertions(+), 43 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index fd88f21..82836e1 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -68,15 +69,6 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie #define SCROLL_ACCEL_DEFAULT 7 -/* Single touch emulation should only begin when no touches are currently down. - * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches - * are down and the touch providing for single touch emulation is lifted, - * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is - * occurring, single_touch_id corresponds with the tracking id of the touch used. - */ -#define NO_TOUCHES -1 -#define SINGLE_TOUCH_UP -2 - /* Touch surface information. Dimension is in hundredths of a mm, min and max * are in units. */ #define MOUSE_DIMENSION_X (float)9056 @@ -125,7 +117,6 @@ struct magicmouse_sc { u8 size; } touches[16]; int tracking_ids[16]; - int single_touch_id; }; static int magicmouse_firm_touch(struct magicmouse_sc *msc) @@ -264,16 +255,14 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda } } - if (down) { + if (down) msc->ntouches++; - if (msc->single_touch_id == NO_TOUCHES) - msc->single_touch_id = id; - } else if (msc->single_touch_id == id) - msc->single_touch_id = SINGLE_TOUCH_UP; + + input_mt_slot(input, id); + input_mt_report_slot_state(input, MT_TOOL_FINGER, down); /* Generate the input events for this touch. */ if (down) { - input_report_abs(input, ABS_MT_TRACKING_ID, id); input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); input_report_abs(input, ABS_MT_ORIENTATION, -orientation); @@ -286,8 +275,6 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ input_event(input, EV_MSC, MSC_RAW, tdata[8]); } - - input_mt_sync(input); } } @@ -308,12 +295,6 @@ static int magicmouse_raw_event(struct hid_device *hdev, for (ii = 0; ii < npoints; ii++) magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); - /* We don't need an MT sync here because trackpad emits a - * BTN_TOUCH event in a new frame when all touches are released. - */ - if (msc->ntouches == 0) - msc->single_touch_id = NO_TOUCHES; - clicks = data[1]; /* The following bits provide a device specific timestamp. They @@ -331,9 +312,6 @@ static int magicmouse_raw_event(struct hid_device *hdev, for (ii = 0; ii < npoints; ii++) magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); - if (msc->ntouches == 0) - input_mt_sync(input); - /* When emulating three-button mode, it is important * to have the current touch information before * generating a click event. @@ -367,24 +345,17 @@ static int magicmouse_raw_event(struct hid_device *hdev, } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ input_report_key(input, BTN_MOUSE, clicks & 1); input_report_key(input, BTN_TOUCH, msc->ntouches > 0); - input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1); - input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2); - input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3); - input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4); - if (msc->single_touch_id >= 0) { - input_report_abs(input, ABS_X, - msc->touches[msc->single_touch_id].x); - input_report_abs(input, ABS_Y, - msc->touches[msc->single_touch_id].y); - } + input_mt_report_pointer_emulation(input, true); } input_sync(input); return 1; } -static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) +static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) { + int error; + __set_bit(EV_KEY, input->evbit); if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { @@ -413,6 +384,7 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); __set_bit(BTN_TOOL_QUADTAP, input->keybit); + __set_bit(BTN_TOOL_QUINTTAP, input->keybit); __set_bit(BTN_TOUCH, input->keybit); __set_bit(INPUT_PROP_POINTER, input->propbit); __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); @@ -421,7 +393,9 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_ABS, input->evbit); - input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); + error = input_mt_init_slots(input, 16); + if (error) + return error; input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, 4, 0); input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, @@ -468,6 +442,8 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_MSC, input->evbit); __set_bit(MSC_RAW, input->mscbit); } + + return 0; } static int magicmouse_input_mapping(struct hid_device *hdev, @@ -506,8 +482,6 @@ static int magicmouse_probe(struct hid_device *hdev, msc->quirks = id->driver_data; hid_set_drvdata(hdev, msc); - msc->single_touch_id = NO_TOUCHES; - ret = hid_parse(hdev); if (ret) { hid_err(hdev, "magicmouse hid parse failed\n"); @@ -523,8 +497,13 @@ static int magicmouse_probe(struct hid_device *hdev, /* We do this after hid-input is done parsing reports so that * hid-input uses the most natural button and axis IDs. */ - if (msc->input) - magicmouse_setup_input(msc->input, hdev); + if (msc->input) { + ret = magicmouse_setup_input(msc->input, hdev); + if (ret) { + hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); + goto err_stop_hw; + } + } if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) report = hid_register_report(hdev, HID_INPUT_REPORT,